watir 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,306 @@
1
+ module Watir
2
+ # Base class for html elements.
3
+ # This is not a class that users would normally access.
4
+ class Element # Wrapper
5
+ include Watir::Exception
6
+ include Container # presumes @container is defined
7
+ attr_accessor :container
8
+
9
+ # number of spaces that separate the property from the value in the to_s method
10
+ TO_S_SIZE = 14
11
+
12
+ # ole_object - the ole object for the element being wrapped
13
+ def initialize(ole_object)
14
+ @o = ole_object
15
+ @original_color = nil
16
+ end
17
+
18
+ # Return the ole object, allowing any methods of the DOM that Watir doesn't support to be used.
19
+ def ole_object # BUG: should use an attribute reader and rename the instance variable
20
+ return @o
21
+ end
22
+ def ole_object=(o)
23
+ @o = o
24
+ end
25
+
26
+ private
27
+ def self.def_wrap(ruby_method_name, ole_method_name=nil)
28
+ ole_method_name = ruby_method_name unless ole_method_name
29
+ class_eval "def #{ruby_method_name}
30
+ assert_exists
31
+ ole_object.invoke('#{ole_method_name}')
32
+ end"
33
+ end
34
+ def self.def_wrap_guard(method_name)
35
+ class_eval "def #{method_name}
36
+ assert_exists
37
+ begin
38
+ ole_object.invoke('#{method_name}')
39
+ rescue
40
+ ''
41
+ end
42
+ end"
43
+ end
44
+
45
+ public
46
+ def assert_exists
47
+ locate if defined?(locate)
48
+ unless ole_object
49
+ raise UnknownObjectException.new("Unable to locate object, using #{@how} and #{@what}")
50
+ end
51
+ end
52
+ def assert_enabled
53
+ unless enabled?
54
+ raise ObjectDisabledException, "object #{@how} and #{@what} is disabled"
55
+ end
56
+ end
57
+
58
+ # return the name of the element (as defined in html)
59
+ def_wrap_guard :name
60
+ # return the id of the element
61
+ def_wrap_guard :id
62
+ # return whether the element is disabled
63
+ def_wrap :disabled
64
+ alias disabled? disabled
65
+ # return the value of the element
66
+ def_wrap_guard :value
67
+ # return the title of the element
68
+ def_wrap_guard :title
69
+ # return the style of the element
70
+ def_wrap_guard :style
71
+
72
+ def_wrap_guard :alt
73
+ def_wrap_guard :src
74
+
75
+ # return the type of the element
76
+ def_wrap_guard :type # input elements only
77
+ # return the url the link points to
78
+ def_wrap :href # link only
79
+ # return the ID of the control that this label is associated with
80
+ def_wrap :for, :htmlFor # label only
81
+ # return the class name of the element
82
+ # raise an ObjectNotFound exception if the object cannot be found
83
+ def_wrap :class_name, :className
84
+ # return the unique COM number for the element
85
+ def_wrap :unique_number, :uniqueNumber
86
+ # Return the outer html of the object - see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/outerhtml.asp?frame=true
87
+ def_wrap :html, :outerHTML
88
+
89
+ # return the text before the element
90
+ def before_text # label only
91
+ assert_exists
92
+ begin
93
+ ole_object.getAdjacentText("afterEnd").strip
94
+ rescue
95
+ ''
96
+ end
97
+ end
98
+
99
+ # return the text after the element
100
+ def after_text # label only
101
+ assert_exists
102
+ begin
103
+ ole_object.getAdjacentText("beforeBegin").strip
104
+ rescue
105
+ ''
106
+ end
107
+ end
108
+
109
+ # Return the innerText of the object
110
+ # Raise an ObjectNotFound exception if the object cannot be found
111
+ def text
112
+ assert_exists
113
+ return ole_object.innerText.strip
114
+ end
115
+
116
+ def ole_inner_elements
117
+ assert_exists
118
+ return ole_object.all
119
+ end
120
+ private :ole_inner_elements
121
+
122
+ def document
123
+ assert_exists
124
+ return ole_object
125
+ end
126
+
127
+ # Return the element immediately containing self.
128
+ def parent
129
+ assert_exists
130
+ result = Element.new(ole_object.parentelement)
131
+ result.set_container self
132
+ result
133
+ end
134
+
135
+ include Comparable
136
+ def <=> other
137
+ assert_exists
138
+ other.assert_exists
139
+ ole_object.sourceindex <=> other.ole_object.sourceindex
140
+ end
141
+
142
+ # Return true if self is contained earlier in the html than other.
143
+ alias :before? :<
144
+ # Return true if self is contained later in the html than other.
145
+ alias :after? :>
146
+
147
+ def typingspeed
148
+ @container.typingspeed
149
+ end
150
+
151
+ def activeObjectHighLightColor
152
+ @container.activeObjectHighLightColor
153
+ end
154
+
155
+ # Return an array with many of the properties, in a format to be used by the to_s method
156
+ def string_creator
157
+ n = []
158
+ n << "type:".ljust(TO_S_SIZE) + self.type
159
+ n << "id:".ljust(TO_S_SIZE) + self.id.to_s
160
+ n << "name:".ljust(TO_S_SIZE) + self.name.to_s
161
+ n << "value:".ljust(TO_S_SIZE) + self.value.to_s
162
+ n << "disabled:".ljust(TO_S_SIZE) + self.disabled.to_s
163
+ return n
164
+ end
165
+ private :string_creator
166
+
167
+ # Display basic details about the object. Sample output for a button is shown.
168
+ # Raises UnknownObjectException if the object is not found.
169
+ # name b4
170
+ # type button
171
+ # id b5
172
+ # value Disabled Button
173
+ # disabled true
174
+ def to_s
175
+ assert_exists
176
+ return string_creator.join("\n")
177
+ end
178
+
179
+ # This method is responsible for setting and clearing the colored highlighting on the currently active element.
180
+ # use :set to set the highlight
181
+ # :clear to clear the highlight
182
+ # TODO: Make this two methods: set_highlight & clear_highlight
183
+ # TODO: Remove begin/rescue blocks
184
+ def highlight(set_or_clear)
185
+ if set_or_clear == :set
186
+ begin
187
+ @original_color ||= style.backgroundColor
188
+ style.backgroundColor = @container.activeObjectHighLightColor
189
+ rescue
190
+ @original_color = nil
191
+ end
192
+ else # BUG: assumes is :clear, but could actually be anything
193
+ begin
194
+ style.backgroundColor = @original_color unless @original_color == nil
195
+ rescue
196
+ # we could be here for a number of reasons...
197
+ # e.g. page may have reloaded and the reference is no longer valid
198
+ ensure
199
+ @original_color = nil
200
+ end
201
+ end
202
+ end
203
+ private :highlight
204
+
205
+ # This method clicks the active element.
206
+ # raises: UnknownObjectException if the object is not found
207
+ # ObjectDisabledException if the object is currently disabled
208
+ def click
209
+ click!
210
+ @container.wait
211
+ end
212
+
213
+ def click_no_wait
214
+ assert_enabled
215
+
216
+ highlight(:set)
217
+ object = "#{self.class}.new(self, :unique_number, #{self.unique_number})"
218
+ @page_container.eval_in_spawned_process(object + ".click!")
219
+ highlight(:clear)
220
+ end
221
+
222
+ def click!
223
+ assert_enabled
224
+
225
+ highlight(:set)
226
+ ole_object.click
227
+ highlight(:clear)
228
+ end
229
+
230
+ # Flash the element the specified number of times.
231
+ # Defaults to 10 flashes.
232
+ def flash number=10
233
+ assert_exists
234
+ number.times do
235
+ highlight(:set)
236
+ sleep 0.05
237
+ highlight(:clear)
238
+ sleep 0.05
239
+ end
240
+ nil
241
+ end
242
+
243
+ # Executes a user defined "fireEvent" for objects with JavaScript events tied to them such as DHTML menus.
244
+ # usage: allows a generic way to fire javascript events on page objects such as "onMouseOver", "onClick", etc.
245
+ # raises: UnknownObjectException if the object is not found
246
+ # ObjectDisabledException if the object is currently disabled
247
+ def fire_event(event)
248
+ assert_enabled
249
+
250
+ highlight(:set)
251
+ ole_object.fireEvent(event)
252
+ @container.wait
253
+ highlight(:clear)
254
+ end
255
+
256
+ # This method sets focus on the active element.
257
+ # raises: UnknownObjectException if the object is not found
258
+ # ObjectDisabledException if the object is currently disabled
259
+ def focus
260
+ assert_enabled
261
+ ole_object.focus
262
+ end
263
+
264
+ # Returns whether this element actually exists.
265
+ def exists?
266
+ begin
267
+ locate if defined?(locate)
268
+ rescue WIN32OLERuntimeError
269
+ @o = nil
270
+ end
271
+ @o ? true: false
272
+ end
273
+ alias :exist? :exists?
274
+
275
+ # Returns true if the element is enabled, false if it isn't.
276
+ # raises: UnknownObjectException if the object is not found
277
+ def enabled?
278
+ assert_exists
279
+ return ! disabled
280
+ end
281
+
282
+ # Get attribute value for any attribute of the element.
283
+ # Returns null if attribute doesn't exist.
284
+ def attribute_value(attribute_name)
285
+ assert_exists
286
+ return ole_object.getAttribute(attribute_name)
287
+ end
288
+
289
+ end
290
+
291
+ class ElementMapper # Still to be used
292
+ include Container
293
+
294
+ def initialize wrapper_class, container, how, what
295
+ @wrapper_class = wrapper_class
296
+ set_container
297
+ @how = how
298
+ @what = what
299
+ end
300
+
301
+ def method_missing method, *args
302
+ locate
303
+ @wrapper_class.new(@o).send(method, *args)
304
+ end
305
+ end
306
+ end
@@ -0,0 +1,82 @@
1
+ module Watir
2
+ # this class is the super class for the iterator classes (buttons, links, spans etc
3
+ # it would normally only be accessed by the iterator methods (spans, links etc) of IE
4
+ class ElementCollections
5
+ include Enumerable
6
+
7
+ # Super class for all the iteractor classes
8
+ # * container - an instance of an IE object
9
+ def initialize(container)
10
+ @container = container
11
+ @page_container = container.page_container
12
+ @length = length # defined by subclasses
13
+
14
+ # set up the items we want to display when the show method is used
15
+ set_show_items
16
+ end
17
+
18
+ private
19
+ def set_show_items
20
+ @show_attributes = AttributeLengthPairs.new("id", 20)
21
+ @show_attributes.add("name", 20)
22
+ end
23
+
24
+ public
25
+ def get_length_of_input_objects(object_type)
26
+ object_types =
27
+ if object_type.kind_of? Array
28
+ object_type
29
+ else
30
+ [object_type]
31
+ end
32
+
33
+ length = 0
34
+ objects = @container.document.getElementsByTagName("INPUT")
35
+ if objects.length > 0
36
+ objects.each do |o|
37
+ length += 1 if object_types.include?(o.invoke("type").downcase)
38
+ end
39
+ end
40
+ return length
41
+ end
42
+
43
+ # iterate through each of the elements in the collection in turn
44
+ def each
45
+ 0.upto(@length-1) { |i| yield iterator_object(i) }
46
+ end
47
+
48
+ # allows access to a specific item in the collection
49
+ def [](n)
50
+ return iterator_object(n-1)
51
+ end
52
+
53
+ # this method is the way to show the objects, normally used from irb
54
+ def show
55
+ s = "index".ljust(6)
56
+ @show_attributes.each do |attribute_length_pair|
57
+ s += attribute_length_pair.attribute.ljust(attribute_length_pair.length)
58
+ end
59
+
60
+ index = 1
61
+ self.each do |o|
62
+ s += "\n"
63
+ s += index.to_s.ljust(6)
64
+ @show_attributes.each do |attribute_length_pair|
65
+ begin
66
+ s += eval('o.ole_object.invoke("#{attribute_length_pair.attribute}")').to_s.ljust(attribute_length_pair.length)
67
+ rescue => e
68
+ s += " ".ljust(attribute_length_pair.length)
69
+ end
70
+ end
71
+ index += 1
72
+ end
73
+ puts s
74
+ end
75
+
76
+ # this method creates an object of the correct type that the iterators use
77
+ private
78
+ def iterator_object(i)
79
+ element_class.new(@container, :index, i + 1)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,151 @@
1
+ module Watir
2
+
3
+ # Forms
4
+
5
+ module FormAccess
6
+ def name
7
+ @ole_object.getAttributeNode('name').value
8
+ end
9
+ def action
10
+ @ole_object.action
11
+ end
12
+ def method
13
+ @ole_object.invoke('method')
14
+ end
15
+ def id
16
+ @ole_object.invoke('id')
17
+ end
18
+ end
19
+
20
+ # wraps around a form OLE object
21
+ class FormWrapper
22
+ include FormAccess
23
+ def initialize(ole_object)
24
+ @ole_object = ole_object
25
+ end
26
+ end
27
+
28
+ # Form Factory object
29
+ class Form < Element
30
+ include FormAccess
31
+ include Container
32
+
33
+ attr_accessor :form
34
+
35
+ # * container - the containing object, normally an instance of IE
36
+ # * how - symbol - how we access the form (:name, :id, :index, :action, :method)
37
+ # * what - what we use to access the form
38
+ def initialize(container, how, what)
39
+ set_container container
40
+ @how = how
41
+ @what = what
42
+
43
+ log "Get form how is #{@how} what is #{@what} "
44
+
45
+ # Get form using xpath.
46
+ if @how == :xpath
47
+ @ole_object = @container.element_by_xpath(@what)
48
+ else
49
+ count = 1
50
+ doc = @container.document
51
+ doc.forms.each do |thisForm|
52
+ next unless @ole_object == nil
53
+
54
+ wrapped = FormWrapper.new(thisForm)
55
+
56
+ log "form on page, name is " + wrapped.name
57
+
58
+ @ole_object =
59
+ case @how
60
+ when :name, :id, :method, :action
61
+ @what.matches(wrapped.send(@how)) ? thisForm : nil
62
+ when :index
63
+ count == @what ? thisForm : nil
64
+ else
65
+ raise MissingWayOfFindingObjectException, "#{how} is an unknown way of finding a form (#{what})"
66
+ end
67
+ count = count +1
68
+ end
69
+ end
70
+ super(@ole_object)
71
+
72
+ copy_test_config container
73
+ end
74
+
75
+ def exists?
76
+ @ole_object ? true : false
77
+ end
78
+ alias :exist? :exists?
79
+
80
+ # Submit the data -- equivalent to pressing Enter or Return to submit a form.
81
+ def submit # XXX use assert_exists
82
+ raise UnknownFormException, "Unable to locate a form using #{@how} and #{@what} " if @ole_object == nil
83
+ @ole_object.submit
84
+ @container.wait
85
+ end
86
+
87
+ def ole_inner_elements # XXX use assert_exists
88
+ raise UnknownFormException, "Unable to locate a form using #{@how} and #{@what} " if @ole_object == nil
89
+ @ole_object.elements
90
+ end
91
+ private :ole_inner_elements
92
+
93
+ def document
94
+ return @ole_object
95
+ end
96
+
97
+ def wait(no_sleep=false)
98
+ @container.wait(no_sleep)
99
+ end
100
+
101
+ # This method is responsible for setting and clearing the colored highlighting on the specified form.
102
+ # use :set to set the highlight
103
+ # :clear to clear the highlight
104
+ def highlight(set_or_clear, element, count)
105
+
106
+ if set_or_clear == :set
107
+ begin
108
+ original_color = element.style.backgroundColor
109
+ original_color = "" if original_color==nil
110
+ element.style.backgroundColor = activeObjectHighLightColor
111
+ rescue => e
112
+ puts e
113
+ puts e.backtrace.join("\n")
114
+ original_color = ""
115
+ end
116
+ @original_styles[count] = original_color
117
+ else
118
+ begin
119
+ element.style.backgroundColor = @original_styles[ count]
120
+ rescue => e
121
+ puts e
122
+ # we could be here for a number of reasons...
123
+ ensure
124
+ end
125
+ end
126
+ end
127
+ private :highlight
128
+
129
+ # causes the object to flash. Normally used in IRB when creating scripts
130
+ # Default is 10
131
+ def flash number=10
132
+ @original_styles = {}
133
+ number.times do
134
+ count = 0
135
+ @ole_object.elements.each do |element|
136
+ highlight(:set, element, count)
137
+ count += 1
138
+ end
139
+ sleep 0.05
140
+ count = 0
141
+ @ole_object.elements.each do |element|
142
+ highlight(:clear, element, count)
143
+ count += 1
144
+ end
145
+ sleep 0.05
146
+ end
147
+ end
148
+
149
+ end # class Form
150
+
151
+ end