walidhalabi-celerity 0.0.6.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/History.txt +75 -0
  2. data/License.txt +621 -0
  3. data/README.txt +73 -0
  4. data/Rakefile +12 -0
  5. data/lib/celerity.rb +74 -0
  6. data/lib/celerity/browser.rb +811 -0
  7. data/lib/celerity/clickable_element.rb +69 -0
  8. data/lib/celerity/collections.rb +156 -0
  9. data/lib/celerity/container.rb +788 -0
  10. data/lib/celerity/default_viewer.rb +10 -0
  11. data/lib/celerity/disabled_element.rb +40 -0
  12. data/lib/celerity/element.rb +313 -0
  13. data/lib/celerity/element_collection.rb +107 -0
  14. data/lib/celerity/element_locator.rb +170 -0
  15. data/lib/celerity/elements/button.rb +43 -0
  16. data/lib/celerity/elements/file_field.rb +25 -0
  17. data/lib/celerity/elements/form.rb +23 -0
  18. data/lib/celerity/elements/frame.rb +75 -0
  19. data/lib/celerity/elements/image.rb +76 -0
  20. data/lib/celerity/elements/label.rb +11 -0
  21. data/lib/celerity/elements/link.rb +30 -0
  22. data/lib/celerity/elements/meta.rb +6 -0
  23. data/lib/celerity/elements/non_control_elements.rb +106 -0
  24. data/lib/celerity/elements/option.rb +32 -0
  25. data/lib/celerity/elements/radio_check.rb +115 -0
  26. data/lib/celerity/elements/select_list.rb +121 -0
  27. data/lib/celerity/elements/table.rb +144 -0
  28. data/lib/celerity/elements/table_cell.rb +29 -0
  29. data/lib/celerity/elements/table_elements.rb +42 -0
  30. data/lib/celerity/elements/table_row.rb +48 -0
  31. data/lib/celerity/elements/text_field.rb +169 -0
  32. data/lib/celerity/exception.rb +77 -0
  33. data/lib/celerity/htmlunit.rb +61 -0
  34. data/lib/celerity/htmlunit/commons-codec-1.3.jar +0 -0
  35. data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  36. data/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
  37. data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  38. data/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
  39. data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  40. data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  41. data/lib/celerity/htmlunit/htmlunit-2.6-SNAPSHOT.jar +0 -0
  42. data/lib/celerity/htmlunit/htmlunit-core-js-2.5.jar +0 -0
  43. data/lib/celerity/htmlunit/nekohtml-1.9.13-20090507.082850-2.jar +0 -0
  44. data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  45. data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  46. data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  47. data/lib/celerity/htmlunit/xercesImpl-2.8.1.jar +0 -0
  48. data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  49. data/lib/celerity/identifier.rb +11 -0
  50. data/lib/celerity/input_element.rb +25 -0
  51. data/lib/celerity/listener.rb +141 -0
  52. data/lib/celerity/resources/no_viewer.png +0 -0
  53. data/lib/celerity/short_inspect.rb +20 -0
  54. data/lib/celerity/util.rb +91 -0
  55. data/lib/celerity/version.rb +10 -0
  56. data/lib/celerity/watir_compatibility.rb +84 -0
  57. data/tasks/jar.rake +57 -0
  58. data/tasks/rdoc.rake +4 -0
  59. metadata +130 -0
@@ -0,0 +1,10 @@
1
+ module Celerity
2
+ class DefaultViewer
3
+ IMAGE = "#{Celerity::DIR}/resources/no_viewer.png"
4
+
5
+ def self.save(path = nil)
6
+ return unless path
7
+ FileUtils.copy(IMAGE, path)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Mixed in to all elements that can have the 'disabled' attribute.
5
+ #
6
+
7
+ module DisabledElement
8
+ include Celerity::Exception
9
+
10
+ #
11
+ # Returns false if the element is disabled.
12
+ #
13
+
14
+ def enabled?
15
+ !disabled?
16
+ end
17
+
18
+ #
19
+ # Returns true if the element is disabled.
20
+ #
21
+
22
+ def disabled?
23
+ assert_exists unless defined?(@object) && @object
24
+ @object.isDisabled
25
+ end
26
+ alias_method :disabled, :disabled?
27
+
28
+ #
29
+ # Used internally.
30
+ # @api private
31
+ #
32
+
33
+ def assert_enabled
34
+ if disabled?
35
+ raise ObjectDisabledException, "Object #{identifier_string} is disabled"
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,313 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Superclass for all HTML elements.
5
+ #
6
+
7
+ class Element
8
+ include Exception
9
+ include Container
10
+
11
+ attr_reader :container
12
+
13
+ # number of spaces that separate the property from the value in the create_string method
14
+ TO_S_SIZE = 14
15
+
16
+ # HTML 4.01 Transitional DTD
17
+ HTML_401_TRANSITIONAL = {
18
+ :core => [:class, :id, :style, :title],
19
+ :cell_halign => [:align, :char, :charoff],
20
+ :cell_valign => [:valign],
21
+ :i18n => [:dir, :lang],
22
+ :event => [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
23
+ :onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup],
24
+ :sloppy => [:name, :value]
25
+ }
26
+
27
+ CELLHALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_halign]
28
+ CELLVALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_valign]
29
+ BASE_ATTRIBUTES = HTML_401_TRANSITIONAL.values_at(:core, :i18n, :event, :sloppy).flatten
30
+ ATTRIBUTES = BASE_ATTRIBUTES
31
+ TAGS = []
32
+
33
+ DEFAULT_HOW = nil
34
+
35
+ # @api private
36
+ def initialize(container, *args)
37
+ self.container = container
38
+
39
+ case args.size
40
+ when 2
41
+ @conditions = { args[0] => args[1] }
42
+ when 1
43
+ if args.first.is_a? Hash
44
+ @conditions = args.first
45
+ elsif (how = self.class::DEFAULT_HOW)
46
+ @conditions = { how => args.first }
47
+ else
48
+ raise ArgumentError, "wrong number of arguments (1 for 2)"
49
+ end
50
+ else
51
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
52
+ end
53
+
54
+ @conditions.freeze
55
+ end
56
+
57
+ #
58
+ # Get the parent element
59
+ # @return [Celerity::Element, nil] subclass of Celerity::Element, or nil if no parent was found
60
+ #
61
+
62
+ def parent
63
+ assert_exists
64
+
65
+ obj = @object.parentNode
66
+ until element_class = Celerity::Util.htmlunit2celerity(obj.class)
67
+ return nil if obj.nil?
68
+ obj = obj.parentNode
69
+ end
70
+
71
+ element_class.new(@container, :object, obj)
72
+ end
73
+
74
+ #
75
+ # Sets the focus to this element.
76
+ #
77
+
78
+ def focus
79
+ assert_exists
80
+ @object.focus
81
+ end
82
+
83
+ #
84
+ # Fires the given event for this element
85
+ #
86
+
87
+ def fire_event(event_name)
88
+ assert_exists
89
+ @object.fireEvent(event_name.sub(/^on/, ''))
90
+ end
91
+
92
+ #
93
+ # Used internally. Find the element on the page.
94
+ # @api private
95
+ #
96
+
97
+ def locate
98
+ @object = ElementLocator.new(@container, self.class).find_by_conditions(@conditions)
99
+ end
100
+
101
+ #
102
+ # Returns the HtmlUnit object backing this element
103
+ #
104
+
105
+ def object
106
+ @object || locate
107
+ end
108
+
109
+ #
110
+ # Returns a JavaScript object representing the receiver
111
+ #
112
+ # @api internal - subject to change
113
+ #
114
+
115
+ def javascript_object
116
+ assert_exists
117
+ @object.getScriptObject
118
+ end
119
+
120
+ #
121
+ # @return [String] A string representation of the element.
122
+ #
123
+
124
+ def to_s
125
+ assert_exists
126
+ create_string(@object)
127
+ end
128
+
129
+ #
130
+ # @param [String, #to_s] The attribute.
131
+ # @return [String] The value of the given attribute.
132
+ #
133
+
134
+ def attribute_value(attribute)
135
+ assert_exists
136
+ @object.getAttribute(attribute.to_s)
137
+ end
138
+
139
+ #
140
+ # Check if the element is visible to the user or not.
141
+ # Note that this only takes the _style attribute_ of the element (and
142
+ # its parents) into account - styles from applied CSS is not considered.
143
+ #
144
+ # @return [boolean]
145
+ #
146
+
147
+ def visible?
148
+ assert_exists
149
+ @object.isDisplayed
150
+ end
151
+
152
+ #
153
+ # Used internally to ensure the element actually exists.
154
+ #
155
+ # @raise [Celerity::Exception::UnknownObjectException] if the element can't be found.
156
+ # @api private
157
+ #
158
+
159
+ def assert_exists
160
+ locate unless @object
161
+ unless @object
162
+ raise UnknownObjectException, "Unable to locate #{self.class.name[/::(.*)$/, 1]}, using #{identifier_string}"
163
+ end
164
+ end
165
+
166
+ #
167
+ # Checks if the element exists.
168
+ # @return [true, false]
169
+ #
170
+
171
+ def exists?
172
+ assert_exists
173
+ true
174
+ rescue UnknownObjectException, UnknownFrameException
175
+ false
176
+ end
177
+ alias_method :exist?, :exists?
178
+
179
+ #
180
+ # Return a text representation of the element as it would appear in a browser.
181
+ #
182
+ # @see inner_text
183
+ # @return [String]
184
+ #
185
+
186
+ def text
187
+ assert_exists
188
+ @object.asText.strip # this must behave like ElementLocator
189
+ end
190
+
191
+ #
192
+ # Return the text content of this DOM node, disregarding its visibility.
193
+ #
194
+ # (Celerity-specific?)
195
+ #
196
+ # @see text
197
+ # @return [String]
198
+ #
199
+
200
+ def inner_text
201
+ assert_exists
202
+ Celerity::Util.normalize_text @object.getTextContent
203
+ end
204
+
205
+ #
206
+ # @return [String] The normative XML representation of the element (including children).
207
+ #
208
+
209
+ def to_xml
210
+ assert_exists
211
+ @object.asXml
212
+ end
213
+ alias_method :asXml, :to_xml
214
+ alias_method :as_xml, :to_xml
215
+ alias_method :html, :to_xml
216
+
217
+ #
218
+ # @return [String] A string representation of the element's attributes.
219
+ #
220
+
221
+ def attribute_string
222
+ assert_exists
223
+
224
+ result = ''
225
+ @object.getAttributes.each do |attribute|
226
+ result << %Q{#{attribute.getName}="#{attribute.getValue}"}
227
+ end
228
+
229
+ result
230
+ end
231
+
232
+ #
233
+ # return the canonical xpath for this element (Celerity-specific)
234
+ #
235
+
236
+ def xpath
237
+ assert_exists
238
+ @object.getCanonicalXPath
239
+ end
240
+
241
+ #
242
+ # Dynamically get element attributes.
243
+ #
244
+ # @see ATTRIBUTES constant for a list of valid methods for a given element.
245
+ #
246
+ # @return [String] The resulting attribute.
247
+ # @raise [NoMethodError] if the element doesn't support this attribute.
248
+ #
249
+
250
+ def method_missing(meth, *args, &blk)
251
+ assert_exists
252
+
253
+ meth = selector_to_attribute(meth)
254
+
255
+ if self.class::ATTRIBUTES.include?(meth) || (self.class == Element && @object.hasAttribute(meth.to_s))
256
+ return @object.getAttribute(meth.to_s)
257
+ end
258
+ Log.warn "Element\#method_missing calling super with #{meth.inspect}"
259
+ super
260
+ end
261
+
262
+ def methods(*args)
263
+ ms = super
264
+ ms += self.class::ATTRIBUTES.map { |e| e.to_s }
265
+ ms.sort
266
+ end
267
+
268
+ def respond_to?(meth, include_private = false)
269
+ meth = selector_to_attribute(meth)
270
+ return true if self.class::ATTRIBUTES.include?(meth)
271
+ super
272
+ end
273
+
274
+ private
275
+
276
+ def create_string(element)
277
+ ret = []
278
+
279
+ unless (tag = element.getTagName).empty?
280
+ ret << "tag:".ljust(TO_S_SIZE) + tag
281
+ end
282
+
283
+ element.getAttributes.each do |attribute|
284
+ ret << " #{attribute.getName}:".ljust(TO_S_SIZE+2) + attribute.getValue.to_s
285
+ end
286
+
287
+ unless (text = element.asText).empty?
288
+ ret << " text:".ljust(TO_S_SIZE+2) + element.asText
289
+ end
290
+
291
+ ret.join("\n")
292
+ end
293
+
294
+ def identifier_string
295
+ if @conditions.size == 1
296
+ how, what = @conditions.to_a.first
297
+ "#{how.inspect} and #{what.inspect}"
298
+ else
299
+ @conditions.inspect
300
+ end
301
+ end
302
+
303
+ def selector_to_attribute(meth)
304
+ case meth
305
+ when :class_name then :class
306
+ when :caption then :value
307
+ when :url then :href
308
+ else meth
309
+ end
310
+ end
311
+
312
+ end # Element
313
+ end # Celerity
@@ -0,0 +1,107 @@
1
+ module Celerity
2
+
3
+ #
4
+ # This class is the superclass for the iterator classes (Buttons, Links, Spans etc.)
5
+ # It would normally only be accessed by the iterator methods (Browser#spans, Browser#links, ...).
6
+ #
7
+
8
+ class ElementCollection
9
+ include Enumerable
10
+
11
+ #
12
+ # @api private
13
+ #
14
+
15
+ def initialize(container, how = nil, what = nil)
16
+ @container = container
17
+ @object = (how == :object ? what : nil)
18
+ @length = length
19
+ end
20
+
21
+ #
22
+ # @return [Fixnum] The number of elements in this collection.
23
+ #
24
+
25
+ def length
26
+ if @object
27
+ @object.length
28
+ else
29
+ @elements ||= ElementLocator.new(@container, element_class).elements_by_idents
30
+ @elements.size
31
+ end
32
+ end
33
+ alias_method :size, :length
34
+
35
+ #
36
+ # @yieldparam [Celerity::Element] element Iterate through the elements in this collection.
37
+ #
38
+
39
+ def each
40
+ if @elements
41
+ @elements.each { |e| yield(element_class.new(@container, :object, e)) }
42
+ else
43
+ 0.upto(@length - 1) { |i| yield iterator_object(i) }
44
+ end
45
+
46
+ @length
47
+ end
48
+
49
+ #
50
+ # Get the element at the given index.
51
+ # By default, this is 1-indexed to keep compatibility with Watir.
52
+ #
53
+ # Also note that because of Watir's lazy loading, this will return an Element
54
+ # instance even if the index is out of bounds.
55
+ #
56
+ # @param [Fixnum] n Index of wanted element, 1-indexed unless Celerity.index_offset is changed.
57
+ # @return [Celerity::Element] Returns a subclass of Celerity::Element
58
+ #
59
+
60
+ def [](n)
61
+ if @elements && @elements[n - Celerity.index_offset]
62
+ element_class.new(@container, :object, @elements[n - Celerity.index_offset])
63
+ else
64
+ iterator_object(n - Celerity.index_offset)
65
+ end
66
+ end
67
+
68
+ #
69
+ # Get the first element in this collection. (Celerity-specific)
70
+ #
71
+ # @return [Celerity::Element] Returns a subclass of Celerity::Element
72
+ #
73
+
74
+ def first
75
+ self[Celerity.index_offset]
76
+ end
77
+
78
+ #
79
+ # Get the last element in this collection. (Celerity-specific)
80
+ #
81
+ # @return [Celerity::Element] Returns a subclass of Celerity::Element
82
+ #
83
+
84
+ def last
85
+ self[Celerity.index_offset - 1]
86
+ end
87
+
88
+ #
89
+ # Note: This can be quite useful in irb:
90
+ #
91
+ # puts browser.text_fields
92
+ #
93
+ # @return [String] A string representation of all elements in this collection.
94
+ #
95
+
96
+ def to_s
97
+ map { |e| e.to_s }.join("\n")
98
+ end
99
+
100
+ private
101
+
102
+ def iterator_object(i)
103
+ element_class.new(@container, :index, i+1)
104
+ end
105
+
106
+ end # ElementCollection
107
+ end # Celerity