watir 2.0.4 → 3.0.0.rc1

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.
@@ -65,8 +65,15 @@ module Watir
65
65
  end
66
66
  end
67
67
 
68
+ class FieldSet < NonControlElement
69
+ Watir::Container.module_eval do
70
+ alias_method :fieldset, :field_set
71
+ alias_method :fieldsets, :field_sets
72
+ end
73
+ end
74
+
68
75
  %w[Pre P Div Span Map Area Li Ul H1 H2 H3 H4 H5 H6
69
- Dl Dt Dd Strong Em Del Font Meta Ol].each do |elem|
76
+ Dl Dt Dd Strong Em Del Ol Body Meta Font Frameset].each do |elem|
70
77
  module_eval %Q{
71
78
  class #{elem} < NonControlElement; end
72
79
  }
@@ -1,34 +1,36 @@
1
1
  module Watir
2
2
 
3
+ module RowContainer
4
+ # Returns a row in the table
5
+ # * index - the index of the row
6
+ def [](index)
7
+ assert_exists
8
+ TableRow.new(self, :ole_object, @o.rows.item(index))
9
+ end
10
+
11
+ def strings
12
+ assert_exists
13
+ rows_memo = []
14
+ @o.rows.each do |row|
15
+ cells_memo = []
16
+ row.cells.each do |cell|
17
+ cells_memo << TableCell.new(self, :ole_object, cell).text
18
+ end
19
+ rows_memo << cells_memo
20
+ end
21
+ rows_memo
22
+ end
23
+
24
+ end
25
+
3
26
  # This class is used for dealing with tables.
4
27
  # Normally a user would not need to create this object as it is returned by the Watir::Container#table method
5
28
  #
6
29
  # many of the methods available to this object are inherited from the Element class
7
30
  #
8
- class Table < Element
9
- include Container
31
+ class Table < NonControlElement
32
+ include RowContainer
10
33
 
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
34
  # override the highlight method, as if the tables rows are set to have a background color,
33
35
  # this will override the table background color, and the normal flash method won't work
34
36
  def highlight(set_or_clear)
@@ -77,74 +79,25 @@ module Watir
77
79
  # iterates through the rows in the table. Yields a TableRow object
78
80
  def each
79
81
  assert_exists
80
- 0.upto(@o.rows.length - 1) do |i|
81
- yield TableRow.new(@container, :ole_object, _row(i))
82
+ @o.rows.each do |row|
83
+ yield TableRow.new(self, :ole_object, row)
82
84
  end
83
85
  end
84
86
 
85
- # Returns a row in the table
86
- # * index - the index of the row
87
- def [](index)
88
- assert_exists
89
- return TableRow.new(@container, :ole_object, _row(index))
90
- end
91
-
92
87
  # Returns the number of rows inside the table, including rows in nested tables.
93
88
  def row_count
94
89
  assert_exists
95
- #return table_body.children.length
96
- return @o.getElementsByTagName("TR").length
90
+ rows.length
97
91
  end
98
92
 
99
- # Returns the number of rows in the table, not including rows in nested tables.
100
- def row_count_excluding_nested_tables
101
- assert_exists
102
- return @o.rows.length
103
- end
104
-
105
93
  # This method returns the number of columns in a row of the table.
106
94
  # Raises an UnknownObjectException if the table doesn't exist.
107
95
  # * index - the index of the row
108
96
  def column_count(index=0)
109
97
  assert_exists
110
- _row(index).cells.length
98
+ row[index].cells.length
111
99
  end
112
100
 
113
- # Returns multi-dimensional array of the cell texts in a table.
114
- #
115
- # Works with tr, th, td elements, colspan, rowspan and nested tables.
116
- # Takes an optional parameter *max_depth*, which is by default 1
117
- def to_a(max_depth=1)
118
- assert_exists
119
- y = []
120
- @o.rows.each do |row|
121
- y << TableRow.new(@container, :ole_object, row).to_a(max_depth)
122
- end
123
- y
124
- end
125
-
126
- def table_body(index=0)
127
- return @o.getElementsByTagName('TBODY')[index]
128
- end
129
- private :table_body
130
-
131
- # returns a watir object
132
- def body(how, what)
133
- return TableBody.new(@container, how, what, self)
134
- end
135
-
136
- # returns a watir object
137
- def bodies
138
- assert_exists
139
- return TableBodies.new(@container, @o)
140
- end
141
-
142
- # returns an ole object
143
- def _row(index)
144
- return @o.invoke("rows").item(index)
145
- end
146
- private :_row
147
-
148
101
  # Returns an array containing all the text values in the specified column
149
102
  # Raises an UnknownCellException if the specified column does not exist in every
150
103
  # Raises an UnknownObjectException if the table doesn't exist.
@@ -161,123 +114,79 @@ module Watir
161
114
  return (0..column_count(rownumber) - 1).collect {|i| self[rownumber][i].text}
162
115
  end
163
116
 
164
- end
165
-
166
- # this class is a collection of the table body objects that exist in the table
167
- # it wouldnt normally be created by a user, but gets returned by the bodies method of the Table object
168
- # many of the methods available to this object are inherited from the Element class
169
- #
170
- class TableBodies < Element
171
- def initialize(container, parent_table)
172
- set_container container
173
- @o = parent_table # in this case, @o is the parent table
174
- end
175
-
176
- # returns the number of TableBodies that exist in the table
177
- def length
178
- assert_exists
179
- return @o.tBodies.length
180
- end
181
-
182
- # returns the n'th Body as a Watir TableBody object
183
- def []n
117
+ def hashes
184
118
  assert_exists
185
- return TableBody.new(@container, :ole_object, ole_table_body_at_index(n))
186
- end
187
-
188
- # returns an ole table body
189
- def ole_table_body_at_index(n)
190
- return @o.tBodies.item(n)
191
- end
192
-
193
- # iterates through each of the TableBodies in the Table. Yields a TableBody object
194
- def each
195
- 0.upto(@o.tBodies.length - 1) do |i|
196
- yield TableBody.new(@container, :ole_object, ole_table_body_at_index(i))
197
- end
198
- end
199
-
200
- end
201
-
202
- # this class is a table body
203
- class TableBody < Element
204
- def locate
205
- @o = nil
206
- if @how == :ole_object
207
- @o = @what # in this case, @o is the table body
208
- elsif @how == :index
209
- @o = @parent_table.bodies.ole_table_body_at_index(@what)
119
+
120
+ headers = []
121
+ @o.rows.item(0).cells.each do |cell|
122
+ headers << TableCell.new(self, :ole_object, cell).text
210
123
  end
211
- @rows = []
212
- if @o
213
- @o.rows.each do |oo|
214
- @rows << TableRow.new(@container, :ole_object, oo)
124
+
125
+ rows_memo = []
126
+ i = 0
127
+ @o.rows.each do |row|
128
+ next if row.uniqueID == @o.rows.item(0).uniqueID
129
+
130
+ cells_memo = {}
131
+ cells = row.cells
132
+ raise "row at index #{i} has #{cells.length} cells, expected #{headers.length}" if cells.length < headers.length
133
+
134
+ j = 0
135
+ cells.each do |cell|
136
+ cells_memo[headers[j]] = TableCell.new(self, :ole_object, cell).text
137
+ j += 1
215
138
  end
139
+
140
+ rows_memo << cells_memo
141
+ i += 1
216
142
  end
217
- end
218
-
219
- def initialize(container, how, what, parent_table=nil)
220
- set_container container
221
- @how = how
222
- @what = what
223
- @parent_table = parent_table
224
- super nil
225
- end
226
-
227
- # returns the specified row as a TableRow object
228
- def [](n)
229
- assert_exists
230
- return @rows[n]
231
- end
232
-
233
- # iterates through all the rows in the table body
234
- def each
235
- locate
236
- 0.upto(length - 1) { |i| yield @rows[i] }
237
- end
238
-
239
- # returns the number of rows in this table body.
240
- def length
241
- return @rows.length
143
+ rows_memo
242
144
  end
243
145
  end
244
-
245
- class TableRow < Element
246
- TAG = "TR"
247
-
248
- def locate
249
- super
250
- cells if @o
251
- end
252
146
 
253
- def cells
254
- return @cells if @cells
147
+ class TableSection < NonControlElement
148
+ include RowContainer
255
149
 
256
- @cells = []
257
- @o.cells.each do |c|
258
- @cells << TableCell.new(@container, :ole_object, c)
150
+ Watir::Container.module_eval do
151
+ def tbody(how={}, what=nil)
152
+ how = {how => what} if what
153
+ TableSection.new(self, how.merge(:tag_name => "tbody"), nil)
259
154
  end
260
- @cells
261
- end
262
155
 
263
- private :cells
264
-
265
- # Returns an initialized instance of a table row
266
- # * o - the object contained in the row
267
- # * container - an instance of an IE object
268
- # * how - symbol - how we access the row
269
- # * what - what we use to access the row - id, index etc. If how is :ole_object then what is a Internet Explorer Raw Row
270
- def initialize(container, how, what)
271
- set_container container
272
- @how = how
273
- @what = what
274
- super nil
156
+ def tbodys(how={}, what=nil)
157
+ how = {how => what} if what
158
+ TableSectionCollection.new(self, how.merge(:tag_name => "tbody"), nil)
159
+ end
160
+
161
+ def thead(how={}, what=nil)
162
+ how = {how => what} if what
163
+ TableSection.new(self, how.merge(:tag_name => "thead"), nil)
164
+ end
165
+
166
+ def theads(how={}, what=nil)
167
+ how = {how => what} if what
168
+ TableSectionCollection.new(self, how.merge(:tag_name => "thead"), nil)
169
+ end
170
+
171
+ def tfoot(how={}, what=nil)
172
+ how = {how => what} if what
173
+ TableSection.new(self, how.merge(:tag_name => "tfoot"), nil)
174
+ end
175
+
176
+ def tfoots(how={}, what=nil)
177
+ how = {how => what} if what
178
+ TableSectionCollection.new(self, how.merge(:tag_name => "tfoot"), nil)
179
+ end
275
180
  end
181
+ end
182
+
183
+ class TableRow < NonControlElement
184
+ TAG = "TR"
276
185
 
277
186
  # this method iterates through each of the cells in the row. Yields a TableCell object
278
187
  def each
279
188
  locate
280
- 0.upto(cells.length - 1) { |i| yield cells[i] }
189
+ cells.each {|cell| yield cell}
281
190
  end
282
191
 
283
192
  # Returns an element from the row as a TableCell object
@@ -299,44 +208,6 @@ module Watir
299
208
  cells.length
300
209
  end
301
210
 
302
- # Returns (multi-dimensional) array of the cell texts in table's row.
303
- #
304
- # Works with th, td elements, colspan, rowspan and nested tables.
305
- # Takes an optional parameter *max_depth*, which is by default 1
306
- def to_a(max_depth=1)
307
- assert_exists
308
- y = []
309
- @o.cells.each do |cell|
310
- inner_tables = cell.getElementsByTagName("TABLE")
311
- inner_tables.each do |inner_table|
312
- # make sure that the inner table is directly child for this cell
313
- if inner_table?(cell, inner_table)
314
- max_depth -= 1
315
- y << Table.new(@container, :ole_object, inner_table).to_a(max_depth) if max_depth >= 1
316
- end
317
- end
318
-
319
- if inner_tables.length == 0
320
- y << cell.innerText.strip
321
- end
322
- end
323
- y
324
- end
325
-
326
- private
327
- # Returns true if inner_table is direct child
328
- # table for cell and there's not any table-s in between
329
- def inner_table?(cell, inner_table)
330
- parent_element = inner_table.parentElement
331
- if parent_element.uniqueID == cell.uniqueID
332
- return true
333
- elsif parent_element.tagName == "TABLE"
334
- return false
335
- else
336
- return inner_table?(cell, parent_element)
337
- end
338
- end
339
-
340
211
  Watir::Container.module_eval do
341
212
  def row(how={}, what=nil)
342
213
  TableRow.new(self, how, what)
@@ -353,33 +224,9 @@ module Watir
353
224
  end
354
225
 
355
226
  # this class is a table cell - when called via the Table object
356
- class TableCell < Element
357
- include Watir::Exception
358
- include Container
227
+ class TableCell < NonControlElement
228
+ TAGS = ["TH", "TD"]
359
229
 
360
- TAG = "TD"
361
-
362
- # Returns an initialized instance of a table cell
363
- # * container - an IE object
364
- # * how - symbol - how we access the cell
365
- # * what - what we use to access the cell - id, name index etc
366
- def initialize(container, how, what)
367
- set_container container
368
- @how = how
369
- @what = what
370
- super nil
371
- end
372
-
373
- def __ole_inner_elements
374
- locate
375
- return @o.all
376
- end
377
-
378
- def document
379
- locate
380
- return @o
381
- end
382
-
383
230
  alias to_s text
384
231
 
385
232
  def colspan
@@ -0,0 +1,68 @@
1
+ module Watir
2
+ class Window
3
+ include ElementExtensions
4
+
5
+ class << self
6
+ attr_accessor :__main_ie
7
+
8
+ def wrap *meths
9
+ meths.each do |meth|
10
+ define_method meth do
11
+ result = nil
12
+ use {result = browser.send(meth)}
13
+ result
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ def initialize(main_browser, locators, browser=nil, &blk)
20
+ valid_locators = [:title, :url, :hwnd, :index]
21
+ locators.each_pair do |k, v|
22
+ raise ArgumentError, "Valid locators are #{valid_locators.join(", ")}" unless valid_locators.include?(k)
23
+ end
24
+ @main_browser = main_browser
25
+ self.class.__main_ie = main_browser.ie
26
+ @locators = locators
27
+ @browser = browser
28
+ end
29
+
30
+ wrap :url, :title, :hwnd, :close
31
+
32
+ def browser
33
+ @browser ||= begin
34
+ IE.find(@locators.keys.first, @locators.values.first)
35
+ end
36
+ end
37
+
38
+ def use(&blk)
39
+ @main_browser.ie = browser.ie
40
+ if blk
41
+ begin
42
+ blk.call
43
+ ensure
44
+ @main_browser.ie = self.class.__main_ie
45
+ # try to find some existing IE when needed
46
+ @main_browser.ie = IE._find(:index, 0) unless @main_browser.exists?
47
+ end
48
+ end
49
+ self
50
+ end
51
+
52
+ def current?
53
+ @main_browser.hwnd == browser.hwnd
54
+ end
55
+
56
+ def ==(other)
57
+ browser.hwnd == other.hwnd
58
+ end
59
+
60
+ alias_method :eql?, :==
61
+
62
+ def present?
63
+ @browser = nil
64
+ browser && browser.exists?
65
+ end
66
+
67
+ end
68
+ end