watir 1.6.5 → 1.6.6.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/CHANGES +461 -326
  2. data/VERSION +1 -0
  3. data/bin/watir-console +6 -6
  4. data/lib/changes.rb +3 -3
  5. data/lib/license.rb +38 -38
  6. data/lib/readme.rb +140 -140
  7. data/lib/watir/WindowHelper.rb +49 -49
  8. data/lib/watir/camel_case.rb +66 -66
  9. data/lib/watir/clickJSDialog.rb +19 -19
  10. data/lib/watir/close_all.rb +37 -37
  11. data/lib/watir/collections.rb +392 -344
  12. data/lib/watir/container.rb +857 -815
  13. data/lib/watir/contrib/enabled_popup.rb +20 -20
  14. data/lib/watir/contrib/ie-new-process.rb +27 -27
  15. data/lib/watir/contrib/page_checker.rb +29 -29
  16. data/lib/watir/cookiemanager.rb +55 -55
  17. data/lib/watir/core.rb +28 -0
  18. data/lib/watir/core_ext.rb +17 -17
  19. data/lib/watir/datahandler.rb +107 -107
  20. data/lib/watir/dialog.rb +46 -46
  21. data/lib/watir/element.rb +351 -343
  22. data/lib/watir/element_collections.rb +97 -97
  23. data/lib/watir/form.rb +170 -170
  24. data/lib/watir/frame.rb +59 -59
  25. data/lib/watir/html_element.rb +22 -0
  26. data/lib/watir/ie-class.rb +1006 -1009
  27. data/lib/watir/ie-process.rb +39 -39
  28. data/lib/watir/ie.rb +70 -133
  29. data/lib/watir/image.rb +130 -130
  30. data/lib/watir/input_elements.rb +614 -572
  31. data/lib/watir/irb-history.rb +30 -30
  32. data/lib/watir/link.rb +64 -64
  33. data/lib/watir/locator.rb +200 -176
  34. data/lib/watir/logger.rb +19 -19
  35. data/lib/watir/modal_dialog.rb +122 -122
  36. data/lib/watir/module.rb +37 -0
  37. data/lib/watir/non_control_elements.rb +145 -145
  38. data/lib/watir/page-container.rb +116 -107
  39. data/lib/watir/popup.rb +29 -29
  40. data/lib/watir/process.rb +19 -19
  41. data/lib/watir/screen_capture.rb +115 -115
  42. data/lib/watir/setFileDialog.rb +16 -16
  43. data/lib/watir/table.rb +395 -362
  44. data/lib/watir/watir_simple.rb +475 -475
  45. data/lib/watir/win32.rb +35 -35
  46. data/lib/watir/win32ole.rb +14 -14
  47. data/lib/watir/winClicker.rb +496 -496
  48. data/rakefile.rb +70 -0
  49. data/unittests/all_tests.rb +10 -10
  50. data/unittests/buttons_xpath_test.rb +69 -69
  51. data/unittests/checkbox_test.rb +179 -179
  52. data/unittests/checkbox_xpath_test.rb +107 -107
  53. data/unittests/click_no_wait_test.rb +21 -0
  54. data/unittests/core_tests.rb +17 -17
  55. data/unittests/css_test.rb +42 -35
  56. data/unittests/defer_test.rb +46 -46
  57. data/unittests/dialog_test.rb +77 -77
  58. data/unittests/div2_xpath_test.rb +21 -21
  59. data/unittests/div_test.rb +188 -188
  60. data/unittests/div_xpath_test.rb +96 -96
  61. data/unittests/element_test.rb +49 -0
  62. data/unittests/errorchecker_test.rb +32 -22
  63. data/unittests/filefield_test.rb +39 -39
  64. data/unittests/filefield_xpath_test.rb +33 -33
  65. data/unittests/form_test.rb +280 -280
  66. data/unittests/form_xpath_test.rb +252 -252
  67. data/unittests/frame_test.rb +155 -155
  68. data/unittests/google_form_test.rb +15 -15
  69. data/unittests/html/JavascriptClick.html +39 -39
  70. data/unittests/html/blankpage.html +11 -11
  71. data/unittests/html/buttons1.html +40 -40
  72. data/unittests/html/checkboxes1.html +89 -89
  73. data/unittests/html/click_no_wait.html +14 -0
  74. data/unittests/html/complex_table.html +36 -36
  75. data/unittests/html/cssTest.html +42 -42
  76. data/unittests/html/depot_store.html +59 -59
  77. data/unittests/html/div.html +93 -93
  78. data/unittests/html/div_xml.html +20 -20
  79. data/unittests/html/fileupload.html +45 -45
  80. data/unittests/html/formTest1.html +38 -38
  81. data/unittests/html/forms2.html +44 -44
  82. data/unittests/html/forms3.html +131 -131
  83. data/unittests/html/forms4.html +27 -27
  84. data/unittests/html/frame_buttons.html +3 -3
  85. data/unittests/html/frame_links.html +3 -3
  86. data/unittests/html/frame_multi.html +4 -4
  87. data/unittests/html/google_india.html +119 -119
  88. data/unittests/html/iframeTest.html +12 -12
  89. data/unittests/html/iframeTest1.html +6 -6
  90. data/unittests/html/iframeTest2.html +5 -5
  91. data/unittests/html/images1.html +66 -66
  92. data/unittests/html/javascriptevents.html +35 -35
  93. data/unittests/html/link_pass.html +10 -10
  94. data/unittests/html/links1.html +38 -38
  95. data/unittests/html/links2.html +10 -10
  96. data/unittests/html/links_multi.html +14 -14
  97. data/unittests/html/list_matters.html +720 -720
  98. data/unittests/html/lists.html +17 -17
  99. data/unittests/html/map_test.html +31 -31
  100. data/unittests/html/modal_dialog.html +10 -10
  101. data/unittests/html/modal_dialog_launcher.html +11 -11
  102. data/unittests/html/nestedFrames.html +6 -6
  103. data/unittests/html/new_browser.html +16 -16
  104. data/unittests/html/pass.html +12 -12
  105. data/unittests/html/popups1.html +59 -59
  106. data/unittests/html/pre.html +27 -27
  107. data/unittests/html/radioButtons1.html +71 -71
  108. data/unittests/html/select_tealeaf.html +54 -54
  109. data/unittests/html/selectboxes1.html +52 -52
  110. data/unittests/html/simple_table.html +26 -26
  111. data/unittests/html/simple_table_buttons.html +104 -104
  112. data/unittests/html/simple_table_columns.html +76 -76
  113. data/unittests/html/table1.html +181 -181
  114. data/unittests/html/tableCell_using_xpath.html +19 -19
  115. data/unittests/html/table_and_tablerow_to_a.html +174 -0
  116. data/unittests/html/textarea.html +30 -30
  117. data/unittests/html/textfields1.html +88 -88
  118. data/unittests/html/textsearch.html +44 -44
  119. data/unittests/html/wallofcheckboxes.html +1003 -1003
  120. data/unittests/html/xpath_nbsp.html +12 -12
  121. data/unittests/ie_exists_test.rb +33 -33
  122. data/unittests/ie_mock.rb +94 -94
  123. data/unittests/ie_test.rb +51 -51
  124. data/unittests/images_test.rb +157 -157
  125. data/unittests/images_xpath_test.rb +91 -91
  126. data/unittests/links_multi_test.rb +48 -48
  127. data/unittests/links_test.rb +175 -175
  128. data/unittests/links_xpath_test.rb +39 -39
  129. data/unittests/lists_test.rb +32 -32
  130. data/unittests/map_test.rb +98 -98
  131. data/unittests/minmax_test.rb +31 -31
  132. data/unittests/navigate_test.rb +39 -39
  133. data/unittests/nbsp_xpath_test.rb +16 -16
  134. data/unittests/non_core_tests.rb +12 -12
  135. data/unittests/other/WindowLogonExample.rb +27 -27
  136. data/unittests/other/WindowLogonExtra.rb +6 -6
  137. data/unittests/other/all_tests_concurrent.rb +57 -57
  138. data/unittests/other/jscriptExtraAlert.rb +6 -6
  139. data/unittests/other/jscriptExtraConfirmCancel.rb +6 -6
  140. data/unittests/other/jscriptExtraConfirmOk.rb +6 -6
  141. data/unittests/other/jscriptPushButton.rb +6 -6
  142. data/unittests/other/jscript_test.rb +63 -63
  143. data/unittests/other/navigate_exception_test.rb +24 -24
  144. data/unittests/other/rexml_unit_test.rb +27 -27
  145. data/unittests/other/screen_capture_test.rb +54 -54
  146. data/unittests/other/testcase_method_order_test.rb +35 -35
  147. data/unittests/other/testcase_verify_test.rb +24 -24
  148. data/unittests/other/wait_until_test.rb +99 -99
  149. data/unittests/pagecontainstext_test.rb +69 -69
  150. data/unittests/parent_child_test.rb +43 -43
  151. data/unittests/perf_test.rb +20 -20
  152. data/unittests/popups_test.rb +43 -43
  153. data/unittests/pre_test.rb +53 -53
  154. data/unittests/radios_test.rb +212 -212
  155. data/unittests/radios_xpath_test.rb +101 -101
  156. data/unittests/security_setting_test.rb +23 -23
  157. data/unittests/selectbox_test.rb +148 -148
  158. data/unittests/selectbox_xpath_test.rb +113 -113
  159. data/unittests/setup.rb +87 -77
  160. data/unittests/speed_settings_test.rb +67 -67
  161. data/unittests/table_and_tablerow_to_a_test.rb +117 -0
  162. data/unittests/table_cell_using_xpath_test.rb +35 -35
  163. data/unittests/table_test.rb +376 -376
  164. data/unittests/table_xpath_test.rb +110 -110
  165. data/unittests/test_tests.rb +9 -9
  166. data/unittests/textarea_test.rb +92 -92
  167. data/unittests/textarea_xpath_test.rb +78 -78
  168. data/unittests/textfield_for_ch_char_test.rb +31 -31
  169. data/unittests/textfields_test.rb +218 -218
  170. data/unittests/textfields_xpath_test.rb +111 -111
  171. data/unittests/window_tests.rb +10 -10
  172. data/unittests/windows/attach_to_existing_window_test.rb +53 -53
  173. data/unittests/windows/attach_to_new_window_test.rb +83 -83
  174. data/unittests/windows/close_window_test.rb +20 -20
  175. data/unittests/windows/frame_links_test.rb +25 -25
  176. data/unittests/windows/ie-each_test.rb +47 -47
  177. data/unittests/windows/iedialog_test.rb +54 -54
  178. data/unittests/windows/js_events_test.rb +42 -55
  179. data/unittests/windows/modal_dialog_test.rb +128 -128
  180. data/unittests/windows/new_test.rb +57 -57
  181. data/unittests/windows/open_close_test.rb +18 -18
  182. data/unittests/windows/send_keys_test.rb +33 -33
  183. data/unittests/xpath_tests.rb +10 -10
  184. metadata +85 -31
  185. data/lib/watir/utils.rb +0 -20
  186. data/lib/watir/version.rb +0 -5
@@ -1,16 +1,16 @@
1
- #
2
- # setFileDialog.rb
3
- #
4
- #
5
- # This file contains the file dialog when it runs as a separate process
6
-
7
- $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
8
- puts $LOAD_PATH
9
- require 'watir/winClicker'
10
-
11
- filepath = "invalid path passed to setFileDialog.rb"
12
- filepath = ARGV[0] unless ARGV[0] == nil
13
-
14
- clicker= WinClicker.new
15
- clicker.setFileRequesterFileName(filepath)
16
- clicker = nil
1
+ #
2
+ # setFileDialog.rb
3
+ #
4
+ #
5
+ # This file contains the file dialog when it runs as a separate process
6
+
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
8
+ puts $LOAD_PATH
9
+ require 'watir/winClicker'
10
+
11
+ filepath = "invalid path passed to setFileDialog.rb"
12
+ filepath = ARGV[0] unless ARGV[0] == nil
13
+
14
+ clicker= WinClicker.new
15
+ clicker.setFileRequesterFileName(filepath)
16
+ clicker = nil
@@ -1,363 +1,396 @@
1
- module Watir
2
-
3
- # This class is used for dealing with tables.
4
- # Normally a user would not need to create this object as it is returned by the Watir::Container#table method
5
- #
6
- # many of the methods available to this object are inherited from the Element class
7
- #
8
- class Table < Element
9
- include Container
10
-
11
- # Returns the table object containing the element
12
- # * container - an instance of an IE object
13
- # * anElement - a Watir object (TextField, Button, etc.)
14
- def Table.create_from_element(container, element)
15
- element.locate if element.respond_to?(:locate)
16
- o = element.ole_object.parentElement
17
- o = o.parentElement until o.tagName == 'TABLE'
18
- new container, :ole_object, o
19
- end
20
-
21
- # Returns an initialized instance of a table object
22
- # * container - the container
23
- # * how - symbol - how we access the table
24
- # * what - what we use to access the table - id, name index etc
25
- def initialize(container, how, what)
26
- set_container container
27
- @how = how
28
- @what = what
29
- super nil
30
- end
31
-
32
- def locate
33
- if @how == :xpath
34
- @o = @container.element_by_xpath(@what)
35
- elsif @how == :ole_object
36
- @o = @what
37
- else
38
- @o = @container.locate_tagged_element('TABLE', @how, @what)
39
- end
40
- end
41
-
42
- # override the highlight method, as if the tables rows are set to have a background color,
43
- # this will override the table background color, and the normal flash method won't work
44
- def highlight(set_or_clear)
45
- if set_or_clear == :set
46
- begin
47
- @original_border = @o.border.to_i
48
- if @o.border.to_i==1
49
- @o.border = 2
50
- else
51
- @o.border = 1
52
- end
53
- rescue
54
- @original_border = nil
55
- end
56
- else
57
- begin
58
- @o.border= @original_border unless @original_border == nil
59
- @original_border = nil
60
- rescue
61
- # we could be here for a number of reasons...
62
- ensure
63
- @original_border = nil
64
- end
65
- end
66
- super
67
- end
68
-
69
- # this method is used to populate the properties in the to_s method
70
- def table_string_creator
71
- n = []
72
- n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
73
- n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
74
- return n
75
- end
76
- private :table_string_creator
77
-
78
- # returns the properties of the object in a string
79
- # raises an ObjectNotFound exception if the object cannot be found
80
- def to_s
81
- assert_exists
82
- r = string_creator
83
- r += table_string_creator
84
- return r.join("\n")
85
- end
86
-
87
- # iterates through the rows in the table. Yields a TableRow object
88
- def each
89
- assert_exists
90
- 1.upto(@o.rows.length) do |i|
91
- yield TableRow.new(@container, :ole_object, _row(i))
92
- end
93
- end
94
-
95
- # Returns a row in the table
96
- # * index - the index of the row
97
- def [](index)
98
- assert_exists
99
- return TableRow.new(@container, :ole_object, _row(index))
100
- end
101
-
102
- # Returns the number of rows inside the table, including rows in nested tables.
103
- def row_count
104
- assert_exists
105
- #return table_body.children.length
106
- return @o.getElementsByTagName("TR").length
107
- end
108
-
109
- # Returns the number of rows in the table, not including rows in nested tables.
110
- def row_count_excluding_nested_tables
111
- assert_exists
112
- return @o.rows.length
113
- end
114
-
115
- # This method returns the number of columns in a row of the table.
116
- # Raises an UnknownObjectException if the table doesn't exist.
117
- # * index - the index of the row
118
- def column_count(index=1)
119
- assert_exists
120
- _row(index).cells.length
121
- end
122
-
123
- # This method returns the table as a 2 dimensional array.
124
- # Don't expect too much if there are nested tables, colspan etc.
125
- # Raises an UnknownObjectException if the table doesn't exist.
126
- # http://www.w3.org/TR/html4/struct/tables.html
127
- def to_a
128
- assert_exists
129
- y = []
130
- table_rows = @o.getElementsByTagName("TR")
131
- for row in table_rows
132
- x = []
133
- for td in row.getElementsbyTagName("TD")
134
- x << td.innerText.strip
135
- end
136
- y << x
137
- end
138
- return y
139
- end
140
-
141
- def table_body(index=1)
142
- return @o.getElementsByTagName('TBODY')[index]
143
- end
144
- private :table_body
145
-
146
- # returns a watir object
147
- def body(how, what)
148
- return TableBody.new(@container, how, what, self)
149
- end
150
-
151
- # returns a watir object
152
- def bodies
153
- assert_exists
154
- return TableBodies.new(@container, @o)
155
- end
156
-
157
- # returns an ole object
158
- def _row(index)
159
- return @o.invoke("rows").item(index - 1)
160
- end
161
- private :_row
162
-
163
- # Returns an array containing all the text values in the specified column
164
- # Raises an UnknownCellException if the specified column does not exist in every
165
- # Raises an UnknownObjectException if the table doesn't exist.
166
- # row of the table
167
- # * columnnumber - column index to extract values from
168
- def column_values(columnnumber)
169
- return (1..row_count).collect {|i| self[i][columnnumber].text}
170
- end
171
-
172
- # Returns an array containing all the text values in the specified row
173
- # Raises an UnknownObjectException if the table doesn't exist.
174
- # * rownumber - row index to extract values from
175
- def row_values(rownumber)
176
- return (1..column_count(rownumber)).collect {|i| self[rownumber][i].text}
177
- end
178
-
179
- end
180
-
181
- # this class is a collection of the table body objects that exist in the table
182
- # it wouldnt normally be created by a user, but gets returned by the bodies method of the Table object
183
- # many of the methods available to this object are inherited from the Element class
184
- #
185
- class TableBodies < Element
186
- def initialize(container, parent_table)
187
- set_container container
188
- @o = parent_table # in this case, @o is the parent table
189
- end
190
-
191
- # returns the number of TableBodies that exist in the table
192
- def length
193
- assert_exists
194
- return @o.tBodies.length
195
- end
196
-
197
- # returns the n'th Body as a Watir TableBody object
198
- def []n
199
- assert_exists
200
- return TableBody.new(@container, :ole_object, ole_table_body_at_index(n))
201
- end
202
-
203
- # returns an ole table body
204
- def ole_table_body_at_index(n)
205
- return @o.tBodies.item(n-1)
206
- end
207
-
208
- # iterates through each of the TableBodies in the Table. Yields a TableBody object
209
- def each
210
- 1.upto(@o.tBodies.length) do |i|
211
- yield TableBody.new(@container, :ole_object, ole_table_body_at_index(i))
212
- end
213
- end
214
-
215
- end
216
-
217
- # this class is a table body
218
- class TableBody < Element
219
- def locate
220
- @o = nil
221
- if @how == :ole_object
222
- @o = @what # in this case, @o is the table body
223
- elsif @how == :index
224
- @o = @parent_table.bodies.ole_table_body_at_index(@what)
225
- end
226
- @rows = []
227
- if @o
228
- @o.rows.each do |oo|
229
- @rows << TableRow.new(@container, :ole_object, oo)
230
- end
231
- end
232
- end
233
-
234
- def initialize(container, how, what, parent_table=nil)
235
- set_container container
236
- @how = how
237
- @what = what
238
- @parent_table = parent_table
239
- super nil
240
- end
241
-
242
- # returns the specified row as a TableRow object
243
- def [](n)
244
- assert_exists
245
- return @rows[n - 1]
246
- end
247
-
248
- # iterates through all the rows in the table body
249
- def each
250
- locate
251
- 0.upto(@rows.length - 1) { |i| yield @rows[i] }
252
- end
253
-
254
- # returns the number of rows in this table body.
255
- def length
256
- return @rows.length
257
- end
258
- end
259
-
260
- class TableRow < Element
261
-
262
- def locate
263
- @o = nil
264
- if @how == :ole_object
265
- @o = @what
266
- elsif @how == :xpath
267
- @o = @container.element_by_xpath(@what)
268
- else
269
- @o = @container.locate_tagged_element("TR", @how, @what)
270
- end
271
- if @o # cant call the assert_exists here, as an exists? method call will fail
272
- @cells = []
273
- @o.cells.each do |oo|
274
- @cells << TableCell.new(@container, :ole_object, oo)
275
- end
276
- end
277
- end
278
-
279
- # Returns an initialized instance of a table row
280
- # * o - the object contained in the row
281
- # * container - an instance of an IE object
282
- # * how - symbol - how we access the row
283
- # * what - what we use to access the row - id, index etc. If how is :ole_object then what is a Internet Explorer Raw Row
284
- def initialize(container, how, what)
285
- set_container container
286
- @how = how
287
- @what = what
288
- super nil
289
- end
290
-
291
- # this method iterates through each of the cells in the row. Yields a TableCell object
292
- def each
293
- locate
294
- 0.upto(@cells.length-1) { |i| yield @cells[i] }
295
- end
296
-
297
- # Returns an element from the row as a TableCell object
298
- def [](index)
299
- assert_exists
300
- if @cells.length < index
301
- raise UnknownCellException, "Unable to locate a cell at index #{index}"
302
- end
303
- return @cells[(index - 1)]
304
- end
305
-
306
- # defaults all missing methods to the array of elements, to be able to
307
- # use the row as an array
308
- # def method_missing(aSymbol, *args)
309
- # return @o.send(aSymbol, *args)
310
- # end
311
- def column_count
312
- locate
313
- @cells.length
314
- end
315
- end
316
-
317
- # this class is a table cell - when called via the Table object
318
- class TableCell < Element
319
- include Watir::Exception
320
- include Container
321
-
322
- def locate
323
- if @how == :xpath
324
- @o = @container.element_by_xpath(@what)
325
- elsif @how == :ole_object
326
- @o = @what
327
- else
328
- @o = @container.locate_tagged_element("TD", @how, @what)
329
- end
330
- end
331
-
332
- # Returns an initialized instance of a table cell
333
- # * container - an IE object
334
- # * how - symbol - how we access the cell
335
- # * what - what we use to access the cell - id, name index etc
336
- def initialize(container, how, what)
337
- set_container container
338
- @how = how
339
- @what = what
340
- super nil
341
- end
342
-
343
- def ole_inner_elements
344
- locate
345
- return @o.all
346
- end
347
- private :ole_inner_elements
348
-
349
- def document
350
- locate
351
- return @o
352
- end
353
-
354
- alias to_s text
355
-
356
- def colspan
357
- locate
358
- @o.colSpan
359
- end
360
-
361
- end
362
-
1
+ module Watir
2
+
3
+ # This class is used for dealing with tables.
4
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#table method
5
+ #
6
+ # many of the methods available to this object are inherited from the Element class
7
+ #
8
+ class Table < Element
9
+ include Container
10
+
11
+ # Returns the table object containing the element
12
+ # * container - an instance of an IE object
13
+ # * anElement - a Watir object (TextField, Button, etc.)
14
+ def Table.create_from_element(container, element)
15
+ element.locate if element.respond_to?(:locate)
16
+ o = element.ole_object.parentElement
17
+ o = o.parentElement until o.tagName == 'TABLE'
18
+ new container, :ole_object, o
19
+ end
20
+
21
+ # Returns an initialized instance of a table object
22
+ # * container - the container
23
+ # * how - symbol - how we access the table
24
+ # * what - what we use to access the table - id, name index etc
25
+ def initialize(container, how, what)
26
+ set_container container
27
+ @how = how
28
+ @what = what
29
+ super nil
30
+ end
31
+
32
+ def locate
33
+ if @how == :xpath
34
+ @o = @container.element_by_xpath(@what)
35
+ elsif @how == :ole_object
36
+ @o = @what
37
+ else
38
+ @o = @container.locate_tagged_element('TABLE', @how, @what)
39
+ end
40
+ end
41
+
42
+ # override the highlight method, as if the tables rows are set to have a background color,
43
+ # this will override the table background color, and the normal flash method won't work
44
+ def highlight(set_or_clear)
45
+ if set_or_clear == :set
46
+ begin
47
+ @original_border = @o.border.to_i
48
+ if @o.border.to_i==1
49
+ @o.border = 2
50
+ else
51
+ @o.border = 1
52
+ end
53
+ rescue
54
+ @original_border = nil
55
+ end
56
+ else
57
+ begin
58
+ @o.border= @original_border unless @original_border == nil
59
+ @original_border = nil
60
+ rescue
61
+ # we could be here for a number of reasons...
62
+ ensure
63
+ @original_border = nil
64
+ end
65
+ end
66
+ super
67
+ end
68
+
69
+ # this method is used to populate the properties in the to_s method
70
+ def table_string_creator
71
+ n = []
72
+ n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
73
+ n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
74
+ return n
75
+ end
76
+ private :table_string_creator
77
+
78
+ # returns the properties of the object in a string
79
+ # raises an ObjectNotFound exception if the object cannot be found
80
+ def to_s
81
+ assert_exists
82
+ r = string_creator
83
+ r += table_string_creator
84
+ return r.join("\n")
85
+ end
86
+
87
+ # iterates through the rows in the table. Yields a TableRow object
88
+ def each
89
+ assert_exists
90
+ 1.upto(@o.rows.length) do |i|
91
+ yield TableRow.new(@container, :ole_object, _row(i))
92
+ end
93
+ end
94
+
95
+ # Returns a row in the table
96
+ # * index - the index of the row
97
+ def [](index)
98
+ assert_exists
99
+ return TableRow.new(@container, :ole_object, _row(index))
100
+ end
101
+
102
+ # Returns the number of rows inside the table, including rows in nested tables.
103
+ def row_count
104
+ assert_exists
105
+ #return table_body.children.length
106
+ return @o.getElementsByTagName("TR").length
107
+ end
108
+
109
+ # Returns the number of rows in the table, not including rows in nested tables.
110
+ def row_count_excluding_nested_tables
111
+ assert_exists
112
+ return @o.rows.length
113
+ end
114
+
115
+ # This method returns the number of columns in a row of the table.
116
+ # Raises an UnknownObjectException if the table doesn't exist.
117
+ # * index - the index of the row
118
+ def column_count(index=1)
119
+ assert_exists
120
+ _row(index).cells.length
121
+ end
122
+
123
+ # Returns multi-dimensional array of the cell texts in a table.
124
+ #
125
+ # Works with tr, th, td elements, colspan, rowspan and nested tables.
126
+ # Takes an optional parameter *max_depth*, which is by default 1
127
+ def to_a(max_depth=1)
128
+ assert_exists
129
+ y = []
130
+ @o.rows.each do |row|
131
+ y << TableRow.new(@container, :ole_object, row).to_a(max_depth)
132
+ end
133
+ y
134
+ end
135
+
136
+ def table_body(index=1)
137
+ return @o.getElementsByTagName('TBODY')[index]
138
+ end
139
+ private :table_body
140
+
141
+ # returns a watir object
142
+ def body(how, what)
143
+ return TableBody.new(@container, how, what, self)
144
+ end
145
+
146
+ # returns a watir object
147
+ def bodies
148
+ assert_exists
149
+ return TableBodies.new(@container, @o)
150
+ end
151
+
152
+ # returns an ole object
153
+ def _row(index)
154
+ return @o.invoke("rows").item(index - 1)
155
+ end
156
+ private :_row
157
+
158
+ # Returns an array containing all the text values in the specified column
159
+ # Raises an UnknownCellException if the specified column does not exist in every
160
+ # Raises an UnknownObjectException if the table doesn't exist.
161
+ # row of the table
162
+ # * columnnumber - column index to extract values from
163
+ def column_values(columnnumber)
164
+ return (1..row_count).collect {|i| self[i][columnnumber].text}
165
+ end
166
+
167
+ # Returns an array containing all the text values in the specified row
168
+ # Raises an UnknownObjectException if the table doesn't exist.
169
+ # * rownumber - row index to extract values from
170
+ def row_values(rownumber)
171
+ return (1..column_count(rownumber)).collect {|i| self[rownumber][i].text}
172
+ end
173
+
174
+ end
175
+
176
+ # this class is a collection of the table body objects that exist in the table
177
+ # it wouldnt normally be created by a user, but gets returned by the bodies method of the Table object
178
+ # many of the methods available to this object are inherited from the Element class
179
+ #
180
+ class TableBodies < Element
181
+ def initialize(container, parent_table)
182
+ set_container container
183
+ @o = parent_table # in this case, @o is the parent table
184
+ end
185
+
186
+ # returns the number of TableBodies that exist in the table
187
+ def length
188
+ assert_exists
189
+ return @o.tBodies.length
190
+ end
191
+
192
+ # returns the n'th Body as a Watir TableBody object
193
+ def []n
194
+ assert_exists
195
+ return TableBody.new(@container, :ole_object, ole_table_body_at_index(n))
196
+ end
197
+
198
+ # returns an ole table body
199
+ def ole_table_body_at_index(n)
200
+ return @o.tBodies.item(n-1)
201
+ end
202
+
203
+ # iterates through each of the TableBodies in the Table. Yields a TableBody object
204
+ def each
205
+ 1.upto(@o.tBodies.length) do |i|
206
+ yield TableBody.new(@container, :ole_object, ole_table_body_at_index(i))
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ # this class is a table body
213
+ class TableBody < Element
214
+ def locate
215
+ @o = nil
216
+ if @how == :ole_object
217
+ @o = @what # in this case, @o is the table body
218
+ elsif @how == :index
219
+ @o = @parent_table.bodies.ole_table_body_at_index(@what)
220
+ end
221
+ @rows = []
222
+ if @o
223
+ @o.rows.each do |oo|
224
+ @rows << TableRow.new(@container, :ole_object, oo)
225
+ end
226
+ end
227
+ end
228
+
229
+ def initialize(container, how, what, parent_table=nil)
230
+ set_container container
231
+ @how = how
232
+ @what = what
233
+ @parent_table = parent_table
234
+ super nil
235
+ end
236
+
237
+ # returns the specified row as a TableRow object
238
+ def [](n)
239
+ assert_exists
240
+ return @rows[n - 1]
241
+ end
242
+
243
+ # iterates through all the rows in the table body
244
+ def each
245
+ locate
246
+ 0.upto(@rows.length - 1) { |i| yield @rows[i] }
247
+ end
248
+
249
+ # returns the number of rows in this table body.
250
+ def length
251
+ return @rows.length
252
+ end
253
+ end
254
+
255
+ class TableRow < Element
256
+
257
+ def locate
258
+ @o = nil
259
+ if @how == :ole_object
260
+ @o = @what
261
+ elsif @how == :xpath
262
+ @o = @container.element_by_xpath(@what)
263
+ else
264
+ @o = @container.locate_tagged_element("TR", @how, @what)
265
+ end
266
+ if @o # cant call the assert_exists here, as an exists? method call will fail
267
+ @cells = []
268
+ @o.cells.each do |oo|
269
+ @cells << TableCell.new(@container, :ole_object, oo)
270
+ end
271
+ end
272
+ end
273
+
274
+ # Returns an initialized instance of a table row
275
+ # * o - the object contained in the row
276
+ # * container - an instance of an IE object
277
+ # * how - symbol - how we access the row
278
+ # * what - what we use to access the row - id, index etc. If how is :ole_object then what is a Internet Explorer Raw Row
279
+ def initialize(container, how, what)
280
+ set_container container
281
+ @how = how
282
+ @what = what
283
+ super nil
284
+ end
285
+
286
+ # this method iterates through each of the cells in the row. Yields a TableCell object
287
+ def each
288
+ locate
289
+ 0.upto(@cells.length-1) { |i| yield @cells[i] }
290
+ end
291
+
292
+ # Returns an element from the row as a TableCell object
293
+ def [](index)
294
+ assert_exists
295
+ if @cells.length < index
296
+ raise UnknownCellException, "Unable to locate a cell at index #{index}"
297
+ end
298
+ return @cells[(index - 1)]
299
+ end
300
+
301
+ # defaults all missing methods to the array of elements, to be able to
302
+ # use the row as an array
303
+ # def method_missing(aSymbol, *args)
304
+ # return @o.send(aSymbol, *args)
305
+ # end
306
+ def column_count
307
+ locate
308
+ @cells.length
309
+ end
310
+
311
+ # Returns (multi-dimensional) array of the cell texts in table's row.
312
+ #
313
+ # Works with th, td elements, colspan, rowspan and nested tables.
314
+ # Takes an optional parameter *max_depth*, which is by default 1
315
+ def to_a(max_depth=1)
316
+ assert_exists
317
+ y = []
318
+ @o.cells.each do |cell|
319
+ inner_tables = cell.getElementsByTagName("TABLE")
320
+ inner_tables.each do |inner_table|
321
+ # make sure that the inner table is directly child for this cell
322
+ if inner_table?(cell, inner_table)
323
+ max_depth -= 1
324
+ y << Table.new(@container, :ole_object, inner_table).to_a(max_depth) if max_depth >= 1
325
+ end
326
+ end
327
+
328
+ if inner_tables.length == 0
329
+ y << cell.innerText.strip
330
+ end
331
+ end
332
+ y
333
+ end
334
+
335
+ private
336
+ # Returns true if inner_table is direct child
337
+ # table for cell and there's not any table-s in between
338
+ def inner_table?(cell, inner_table)
339
+ parent_element = inner_table.parentElement
340
+ if parent_element.uniqueID == cell.uniqueID
341
+ return true
342
+ elsif parent_element.tagName == "TABLE"
343
+ return false
344
+ else
345
+ return inner_table?(cell, parent_element)
346
+ end
347
+ end
348
+ end
349
+
350
+ # this class is a table cell - when called via the Table object
351
+ class TableCell < Element
352
+ include Watir::Exception
353
+ include Container
354
+
355
+ def locate
356
+ if @how == :xpath
357
+ @o = @container.element_by_xpath(@what)
358
+ elsif @how == :ole_object
359
+ @o = @what
360
+ else
361
+ @o = @container.locate_tagged_element("TD", @how, @what)
362
+ end
363
+ end
364
+
365
+ # Returns an initialized instance of a table cell
366
+ # * container - an IE object
367
+ # * how - symbol - how we access the cell
368
+ # * what - what we use to access the cell - id, name index etc
369
+ def initialize(container, how, what)
370
+ set_container container
371
+ @how = how
372
+ @what = what
373
+ super nil
374
+ end
375
+
376
+ def ole_inner_elements
377
+ locate
378
+ return @o.all
379
+ end
380
+ private :ole_inner_elements
381
+
382
+ def document
383
+ locate
384
+ return @o
385
+ end
386
+
387
+ alias to_s text
388
+
389
+ def colspan
390
+ locate
391
+ @o.colSpan
392
+ end
393
+
394
+ end
395
+
363
396
  end