watir 1.9.2 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/CHANGES +27 -0
  2. data/VERSION +1 -1
  3. data/lib/watir/collections.rb +29 -387
  4. data/lib/watir/container.rb +14 -784
  5. data/lib/watir/dialogs/javascript.rb +7 -0
  6. data/lib/watir/element.rb +24 -4
  7. data/lib/watir/element_collections.rb +35 -57
  8. data/lib/watir/form.rb +13 -33
  9. data/lib/watir/frame.rb +14 -27
  10. data/lib/watir/html_element.rb +11 -3
  11. data/lib/watir/ie-class.rb +10 -1
  12. data/lib/watir/image.rb +3 -11
  13. data/lib/watir/input_elements.rb +11 -11
  14. data/lib/watir/link.rb +8 -15
  15. data/lib/watir/locator.rb +98 -73
  16. data/lib/watir/modal_dialog.rb +7 -1
  17. data/lib/watir/non_control_elements.rb +5 -89
  18. data/lib/watir/table.rb +46 -49
  19. data/unittests/checkbox_test.rb +39 -44
  20. data/unittests/checkbox_xpath_test.rb +2 -2
  21. data/unittests/css_test.rb +1 -1
  22. data/unittests/div_test.rb +43 -43
  23. data/unittests/div_xpath_test.rb +12 -12
  24. data/unittests/element_collections_test.rb +85 -0
  25. data/unittests/element_test.rb +4 -4
  26. data/unittests/form_test.rb +16 -19
  27. data/unittests/form_xpath_test.rb +6 -6
  28. data/unittests/frame_test.rb +114 -120
  29. data/unittests/html/multiple_specifiers.html +64 -0
  30. data/unittests/ie_test.rb +5 -5
  31. data/unittests/images_test.rb +12 -12
  32. data/unittests/index_specifier_test.rb +32 -0
  33. data/unittests/js_events_test.rb +3 -3
  34. data/unittests/links_multi_test.rb +4 -4
  35. data/unittests/links_test.rb +20 -20
  36. data/unittests/lists_test.rb +1 -1
  37. data/unittests/map_test.rb +1 -1
  38. data/unittests/multiple_specifiers_test.rb +29 -0
  39. data/unittests/no_wait_test.rb +2 -2
  40. data/unittests/pagecontainstext_test.rb +2 -2
  41. data/unittests/parent_child_test.rb +2 -2
  42. data/unittests/pre_test.rb +5 -5
  43. data/unittests/radios_test.rb +41 -60
  44. data/unittests/selectbox_test.rb +15 -15
  45. data/unittests/speed_settings_test.rb +2 -2
  46. data/unittests/table_and_tablerow_to_a_test.rb +7 -7
  47. data/unittests/table_test.rb +81 -94
  48. data/unittests/textfields_test.rb +26 -27
  49. data/unittests/windows/attach_to_new_window_test.rb +1 -1
  50. data/watir-rdoc.rb +1 -1
  51. data/watir.gemspec +1 -2
  52. metadata +34 -40
@@ -16,6 +16,8 @@ module Watir
16
16
  how = :value
17
17
  when :method
18
18
  how = :form_method
19
+ when :value
20
+ what = what.is_a?(Regexp) ? what : what.to_s
19
21
  end
20
22
 
21
23
  @specifiers[how] = what
@@ -23,41 +25,59 @@ module Watir
23
25
  end
24
26
 
25
27
  def match_with_specifiers?(element)
26
- @specifiers.each do |how, what|
27
- next if how == :index
28
- return false unless match? element, how, what
28
+ @specifiers.all? {|how, what| how == :index || match?(element, how, what)}
29
+ end
30
+
31
+ def set_specifier(how, what=nil)
32
+ specifiers = what ? {how => what} : how
33
+ @specifiers = {:index => Watir::Browser.base_index} # default if not specified
34
+ normalize_specifiers! specifiers
35
+ end
36
+
37
+ def locate_by_xpath_css_ole
38
+ if @specifiers[:xpath]
39
+ return @container.element_by_xpath(@specifiers[:xpath])
40
+ elsif @specifiers[:css]
41
+ return @container.element_by_css(@specifiers[:css])
42
+ elsif @specifiers[:ole_object]
43
+ return @specifiers[:ole_object]
29
44
  end
30
- return true
31
45
  end
32
46
  end
33
47
 
34
48
  class TaggedElementLocator < Locator
35
- def initialize(container, tag)
49
+ def initialize(container, tag, klass)
36
50
  @container = container
37
51
  @tag = tag
38
- end
39
-
40
- def set_specifier(how, what)
41
- if how.class == Hash and what.nil?
42
- specifiers = how
43
- else
44
- specifiers = {how => what}
45
- end
46
-
47
- @specifiers = {:index => 1} # default if not specified
48
- normalize_specifiers! specifiers
52
+ @klass = klass || Element
49
53
  end
50
54
 
51
55
  def each_element tag
52
- @container.document.getElementsByTagName(tag).each do |ole_element|
53
- yield Element.new(ole_element)
56
+ @container.document.getElementsByTagName(tag).each do |ole_object|
57
+ if @klass == Element
58
+ element = Element.new(ole_object)
59
+ else
60
+ element = @klass.new(@container, @specifiers, nil)
61
+ element.ole_object = ole_object
62
+ def element.locate; @o; end unless @klass == TableRow
63
+ end
64
+ yield element
54
65
  end
55
66
  end
56
67
 
57
- def locate
58
- count = 0
59
- each_element(@tag) do |element|
68
+ def each
69
+ each_element(@tag) do |element|
60
70
  next unless match_with_specifiers?(element)
71
+ yield element
72
+ end
73
+ nil
74
+ end
75
+
76
+ def locate
77
+ return locate_by_xpath_css_ole if @specifiers[:xpath] || @specifiers[:css] || @specifiers[:ole_object]
78
+
79
+ count = Watir::Browser.base_index - 1
80
+ each do |element|
61
81
  count += 1
62
82
  return element.ole_object if count == @specifiers[:index]
63
83
  end # elements
@@ -75,7 +95,7 @@ module Watir
75
95
  when 0
76
96
  what.matches method.call
77
97
  when 1
78
- method.call(what)
98
+ method.call(what)
79
99
  else
80
100
  raise MissingWayOfFindingObjectException,
81
101
  "#{how} is an unknown way of finding a <#{@tag}> element (#{what})"
@@ -85,38 +105,56 @@ module Watir
85
105
  end
86
106
 
87
107
  class FrameLocator < TaggedElementLocator
88
- attr_accessor :tag
89
-
90
108
  def initialize(container)
91
109
  @container = container
110
+ @tags = Frame::TAG
92
111
  end
93
112
 
94
113
  def each_element tag
95
114
  frames = @container.document.frames
96
115
  i = 0
97
- @container.document.getElementsByTagName(tag).each do |frame|
98
- element = Element.new(frame)
99
- document = frames.item(i)
100
- yield element, document
116
+ @container.document.getElementsByTagName(tag).each do |ole_object|
117
+ frame = Frame.new(@container, @specifiers, nil)
118
+ frame.ole_object = ole_object
119
+ frame.document = frames.item(i)
120
+ def frame.locate; @o; end
121
+ yield frame
101
122
  i += 1
102
123
  end
103
124
  end
104
125
 
126
+ def each
127
+ @tags.each do |tag|
128
+ each_element(tag) do |element|
129
+ next unless match_with_specifiers?(element)
130
+ yield element
131
+ end
132
+ end
133
+ nil
134
+ end
135
+
105
136
  def locate
106
- count = 0
107
- each_element(@tag) do |element, document|
108
- next unless match_with_specifiers?(element)
137
+ return locate_by_xpath_css_ole if @specifiers[:xpath] || @specifiers[:css] || @specifiers[:ole_object]
138
+
139
+ count = Watir::Browser.base_index - 1
140
+ each do |frame|
109
141
  count += 1
110
- return element.ole_object, document if count == @specifiers[:index]
111
- end # elements
112
- nil
142
+ return frame.ole_object, frame.document if count == @specifiers[:index]
143
+ end
113
144
  end
114
145
  end
115
146
 
116
147
  class FormLocator < TaggedElementLocator
148
+ def initialize(container)
149
+ super(container, 'FORM', Form)
150
+ end
151
+
117
152
  def each_element(tag)
118
153
  @container.document.forms.each do |form|
119
- yield FormElement.new(form)
154
+ form_element = Form.new(@container, @specifiers, nil)
155
+ form_element.ole_object = form
156
+ def form_element.locate; @o; end
157
+ yield form_element
120
158
  end
121
159
  end
122
160
  end
@@ -125,48 +163,45 @@ module Watir
125
163
 
126
164
  attr_accessor :document, :element, :elements, :klass
127
165
 
128
- def initialize container, types
166
+ def initialize container, types, klass
129
167
  @container = container
130
168
  @types = types
131
169
  @elements = nil
132
- @klass = Element
170
+ @klass = klass || Element
133
171
  end
134
-
135
- def specifier= arg
136
- how, what, value = arg
137
172
 
138
- if how.class == Hash and what.nil?
139
- specifiers = how
140
- else
141
- specifiers = {how => what}
142
- end
143
-
144
- @specifiers = {:index => 1} # default if not specified
145
- if value
146
- @specifiers[:value] = value.is_a?(Regexp) ? value : value.to_s
147
- end
148
-
149
- normalize_specifiers! specifiers
150
- end
151
-
152
- def locate
153
- count = 0
173
+ def each_element
154
174
  @elements.each do |object|
155
175
  if @klass == Element
156
176
  element = Element.new(object)
157
177
  else
158
178
  element = @klass.new(@container, @specifiers, nil)
159
179
  element.ole_object = object
160
- def element.locate; @o; end
180
+ def element.locate; @o; end
161
181
  end
182
+ yield element
183
+ end
184
+ nil
185
+ end
162
186
 
163
- next unless @types.include?(element.type) && match_with_specifiers?(element)
164
-
187
+ def locate
188
+ return locate_by_xpath_css_ole if @specifiers[:xpath] || @specifiers[:css] || @specifiers[:ole_object]
189
+
190
+ count = Watir::Browser.base_index - 1
191
+ each do |element|
165
192
  count += 1
166
- return object if count == @specifiers[:index]
193
+ return element.ole_object if count == @specifiers[:index]
167
194
  end
168
- nil
169
195
  end
196
+
197
+ def each
198
+ each_element do |element|
199
+ next unless @types.include?(element.type) && match_with_specifiers?(element)
200
+ yield element
201
+ end
202
+ nil
203
+ end
204
+
170
205
  # return true if the element matches the provided how and what
171
206
  def match? element, how, what
172
207
  begin
@@ -191,7 +226,7 @@ module Watir
191
226
 
192
227
  the_id = @specifiers[:id]
193
228
  if the_id && the_id.class == String &&
194
- @specifiers[:index] == 1 && @specifiers.length == 2
229
+ @specifiers[:index] == Watir::Browser.base_index && @specifiers.length == 2
195
230
  @element = @document.getElementById(the_id) rescue nil
196
231
  # Return if our fast match really HAS a matching :id
197
232
  return true if @element && @element.invoke('id') == the_id && @types.include?(@element.getAttribute('type'))
@@ -209,17 +244,7 @@ module Watir
209
244
  # get all the elements by forcing @tag to be '*'
210
245
  class ElementLocator < TaggedElementLocator
211
246
  def initialize(container)
212
- @container = container
247
+ super(container, "*", Element)
213
248
  end
214
-
215
- def each
216
- count = 0
217
- each_element('*') do |element|
218
- next unless match_with_specifiers?(element)
219
- yield element
220
- end
221
- nil
222
- end
223
-
224
249
  end
225
250
  end
@@ -76,5 +76,11 @@ module Watir
76
76
  return @modal.exists?
77
77
  end
78
78
  alias :exist? :exists?
79
+
80
+ Watir::Container.module_eval do
81
+ def modal_dialog(*args)
82
+ ModalDialog.new(self)
83
+ end
84
+ end
79
85
  end
80
- end
86
+ end
@@ -6,28 +6,8 @@ module Watir
6
6
  # many of the methods available to this object are inherited from the Element class
7
7
  #
8
8
  class NonControlElement < Element
9
-
10
- def self.inherited subclass
11
- class_name = Watir::Util.demodulize(subclass.to_s)
12
- method_name = Watir::Util.underscore(class_name)
13
- Watir::Container.module_eval <<-RUBY
14
- def #{method_name}(how, what=nil)
15
- return #{class_name}.new(self, how, what)
16
- end
17
- RUBY
18
- end
19
9
  include Watir::Exception
20
10
 
21
- def locate
22
- if @how == :xpath
23
- @o = @container.element_by_xpath(@what)
24
- elsif @how == :css
25
- @o = @container.element_by_css(@what)
26
- else
27
- @o = @container.locate_tagged_element(self.class::TAG, @how, @what)
28
- end
29
- end
30
-
31
11
  def initialize(container, how, what)
32
12
  set_container container
33
13
  @how = how
@@ -54,38 +34,8 @@ module Watir
54
34
  end
55
35
  end
56
36
 
57
-
58
- class Pre < NonControlElement
59
- TAG = 'PRE'
60
- end
61
-
62
- class P < NonControlElement
63
- TAG = 'P'
64
- end
65
-
66
- # this class is used to deal with Div tags in the html page. http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/div.asp?frame=true
67
- # It would not normally be created by users
68
- class Div < NonControlElement
69
- TAG = 'DIV'
70
- end
71
-
72
- # this class is used to deal with Span tags in the html page. It would not normally be created by users
73
- class Span < NonControlElement
74
- TAG = 'SPAN'
75
- end
76
-
77
- class Map < NonControlElement
78
- TAG = 'MAP'
79
- end
80
-
81
- class Area < NonControlElement
82
- TAG = 'AREA'
83
- end
84
-
85
37
  # Accesses Label element on the html page - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/label.asp?frame=true
86
38
  class Label < NonControlElement
87
- TAG = 'LABEL'
88
-
89
39
  # this method is used to populate the properties in the to_s method
90
40
  def label_string_creator
91
41
  n = []
@@ -105,44 +55,10 @@ module Watir
105
55
  end
106
56
  end
107
57
 
108
- class Li < NonControlElement
109
- TAG = 'LI'
110
- end
111
- class Ul < NonControlElement
112
- TAG = 'UL'
113
- end
114
- class H1 < NonControlElement
115
- TAG = 'H1'
116
- end
117
- class H2 < NonControlElement
118
- TAG = 'H2'
119
- end
120
- class H3 < NonControlElement
121
- TAG = 'H3'
122
- end
123
- class H4 < NonControlElement
124
- TAG = 'H4'
125
- end
126
- class H5 < NonControlElement
127
- TAG = 'H5'
58
+ %w[pre p div span map area li ul h1 h2 h3 h4 h5 h6 dl dt dd strong em].each do |elem|
59
+ module_eval %Q{
60
+ class #{elem.capitalize} < NonControlElement; end
61
+ }
128
62
  end
129
- class H6 < NonControlElement
130
- TAG = 'H6'
131
- end
132
- class Dl < NonControlElement
133
- TAG = 'DL'
134
- end
135
- class Dt < NonControlElement
136
- TAG = 'DT'
137
- end
138
- class Dd < NonControlElement
139
- TAG = 'DD'
140
- end
141
- class Strong < NonControlElement
142
- TAG = 'STRONG'
143
- end
144
- class Em < NonControlElement
145
- TAG = 'EM'
146
- end
147
-
63
+
148
64
  end
@@ -7,7 +7,7 @@ module Watir
7
7
  #
8
8
  class Table < Element
9
9
  include Container
10
-
10
+
11
11
  # Returns the table object containing the element
12
12
  # * container - an instance of an IE object
13
13
  # * anElement - a Watir object (TextField, Button, etc.)
@@ -29,18 +29,6 @@ module Watir
29
29
  super nil
30
30
  end
31
31
 
32
- def locate
33
- if @how == :xpath
34
- @o = @container.element_by_xpath(@what)
35
- elsif @how == :css
36
- @o = @container.element_by_css(@what)
37
- elsif @how == :ole_object
38
- @o = @what
39
- else
40
- @o = @container.locate_tagged_element('TABLE', @how, @what)
41
- end
42
- end
43
-
44
32
  # override the highlight method, as if the tables rows are set to have a background color,
45
33
  # this will override the table background color, and the normal flash method won't work
46
34
  def highlight(set_or_clear)
@@ -89,7 +77,7 @@ module Watir
89
77
  # iterates through the rows in the table. Yields a TableRow object
90
78
  def each
91
79
  assert_exists
92
- 1.upto(@o.rows.length) do |i|
80
+ 0.upto(@o.rows.length - 1) do |i|
93
81
  yield TableRow.new(@container, :ole_object, _row(i))
94
82
  end
95
83
  end
@@ -117,7 +105,7 @@ module Watir
117
105
  # This method returns the number of columns in a row of the table.
118
106
  # Raises an UnknownObjectException if the table doesn't exist.
119
107
  # * index - the index of the row
120
- def column_count(index=1)
108
+ def column_count(index=0)
121
109
  assert_exists
122
110
  _row(index).cells.length
123
111
  end
@@ -135,7 +123,7 @@ module Watir
135
123
  y
136
124
  end
137
125
 
138
- def table_body(index=1)
126
+ def table_body(index=0)
139
127
  return @o.getElementsByTagName('TBODY')[index]
140
128
  end
141
129
  private :table_body
@@ -153,7 +141,7 @@ module Watir
153
141
 
154
142
  # returns an ole object
155
143
  def _row(index)
156
- return @o.invoke("rows").item(index - 1)
144
+ return @o.invoke("rows").item(index)
157
145
  end
158
146
  private :_row
159
147
 
@@ -163,14 +151,14 @@ module Watir
163
151
  # row of the table
164
152
  # * columnnumber - column index to extract values from
165
153
  def column_values(columnnumber)
166
- return (1..row_count).collect {|i| self[i][columnnumber].text}
154
+ return (0..row_count - 1).collect {|i| self[i][columnnumber].text}
167
155
  end
168
156
 
169
157
  # Returns an array containing all the text values in the specified row
170
158
  # Raises an UnknownObjectException if the table doesn't exist.
171
159
  # * rownumber - row index to extract values from
172
160
  def row_values(rownumber)
173
- return (1..column_count(rownumber)).collect {|i| self[rownumber][i].text}
161
+ return (0..column_count(rownumber) - 1).collect {|i| self[rownumber][i].text}
174
162
  end
175
163
 
176
164
  end
@@ -199,12 +187,12 @@ module Watir
199
187
 
200
188
  # returns an ole table body
201
189
  def ole_table_body_at_index(n)
202
- return @o.tBodies.item(n-1)
190
+ return @o.tBodies.item(n)
203
191
  end
204
192
 
205
193
  # iterates through each of the TableBodies in the Table. Yields a TableBody object
206
194
  def each
207
- 1.upto(@o.tBodies.length) do |i|
195
+ 0.upto(@o.tBodies.length - 1) do |i|
208
196
  yield TableBody.new(@container, :ole_object, ole_table_body_at_index(i))
209
197
  end
210
198
  end
@@ -239,13 +227,13 @@ module Watir
239
227
  # returns the specified row as a TableRow object
240
228
  def [](n)
241
229
  assert_exists
242
- return @rows[n - 1]
230
+ return @rows[n]
243
231
  end
244
232
 
245
233
  # iterates through all the rows in the table body
246
234
  def each
247
235
  locate
248
- 0.upto(@rows.length - 1) { |i| yield @rows[i] }
236
+ 0.upto(length - 1) { |i| yield @rows[i] }
249
237
  end
250
238
 
251
239
  # returns the number of rows in this table body.
@@ -255,18 +243,10 @@ module Watir
255
243
  end
256
244
 
257
245
  class TableRow < Element
246
+ TAG = "TR"
258
247
 
259
248
  def locate
260
- @o = nil
261
- if @how == :ole_object
262
- @o = @what
263
- elsif @how == :xpath
264
- @o = @container.element_by_xpath(@what)
265
- elsif @how == :css
266
- @o = @container.element_by_css(@what)
267
- else
268
- @o = @container.locate_tagged_element("TR", @how, @what)
269
- end
249
+ super
270
250
  if @o # cant call the assert_exists here, as an exists? method call will fail
271
251
  @cells = []
272
252
  @o.cells.each do |oo|
@@ -290,16 +270,16 @@ module Watir
290
270
  # this method iterates through each of the cells in the row. Yields a TableCell object
291
271
  def each
292
272
  locate
293
- 0.upto(@cells.length-1) { |i| yield @cells[i] }
273
+ 0.upto(@cells.length - 1) { |i| yield @cells[i] }
294
274
  end
295
275
 
296
276
  # Returns an element from the row as a TableCell object
297
277
  def [](index)
298
278
  assert_exists
299
- if @cells.length < index
279
+ if @cells.length <= index
300
280
  raise UnknownCellException, "Unable to locate a cell at index #{index}"
301
281
  end
302
- return @cells[(index - 1)]
282
+ return @cells[index]
303
283
  end
304
284
 
305
285
  # defaults all missing methods to the array of elements, to be able to
@@ -349,24 +329,28 @@ module Watir
349
329
  return inner_table?(cell, parent_element)
350
330
  end
351
331
  end
332
+
333
+ Watir::Container.module_eval do
334
+ def row(how={}, what=nil)
335
+ TableRow.new(self, how, what)
336
+ end
337
+
338
+ alias_method :tr, :row
339
+
340
+ def rows(how={}, what=nil)
341
+ TableRows.new(self, how, what)
342
+ end
343
+
344
+ alias_method :trs, :rows
345
+ end
352
346
  end
353
347
 
354
348
  # this class is a table cell - when called via the Table object
355
349
  class TableCell < Element
356
350
  include Watir::Exception
357
351
  include Container
358
-
359
- def locate
360
- if @how == :xpath
361
- @o = @container.element_by_xpath(@what)
362
- elsif @how == :css
363
- @o = @container.element_by_css(@what)
364
- elsif @how == :ole_object
365
- @o = @what
366
- else
367
- @o = @container.locate_tagged_element("TD", @how, @what)
368
- end
369
- end
352
+
353
+ TAG = "TD"
370
354
 
371
355
  # Returns an initialized instance of a table cell
372
356
  # * container - an IE object
@@ -397,6 +381,19 @@ module Watir
397
381
  @o.colSpan
398
382
  end
399
383
 
384
+ Watir::Container.module_eval do
385
+ def cell(how={}, what=nil)
386
+ TableCell.new(self, how, what)
387
+ end
388
+
389
+ alias_method :td, :cell
390
+
391
+ def cells(how={}, what=nil)
392
+ TableCells.new(self, how, what)
393
+ end
394
+
395
+ alias_method :tds, :cells
396
+ end
400
397
  end
401
398
 
402
- end
399
+ end