walidhalabi-celerity 0.0.6.11

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.
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