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.
- data/CHANGES +41 -0
- data/VERSION +1 -1
- data/lib/watir/collections.rb +9 -17
- data/lib/watir/container.rb +2 -14
- data/lib/watir/core.rb +1 -0
- data/lib/watir/dialogs/file_field.rb +4 -2
- data/lib/watir/element.rb +146 -90
- data/lib/watir/element_collections.rb +13 -11
- data/lib/watir/form.rb +4 -2
- data/lib/watir/frame.rb +15 -3
- data/lib/watir/ie-class.rb +100 -128
- data/lib/watir/image.rb +10 -13
- data/lib/watir/input_elements.rb +92 -156
- data/lib/watir/locator.rb +61 -66
- data/lib/watir/non_control_elements.rb +8 -1
- data/lib/watir/table.rb +89 -242
- data/lib/watir/window.rb +68 -0
- metadata +21 -14
@@ -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
|
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
|
}
|
data/lib/watir/table.rb
CHANGED
@@ -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 <
|
9
|
-
include
|
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
|
-
|
81
|
-
yield TableRow.new(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
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
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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
|
-
|
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
|
-
|
254
|
-
|
147
|
+
class TableSection < NonControlElement
|
148
|
+
include RowContainer
|
255
149
|
|
256
|
-
|
257
|
-
|
258
|
-
|
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
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
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
|
-
|
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 <
|
357
|
-
|
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
|
data/lib/watir/window.rb
ADDED
@@ -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
|