fletcherm-culerity 0.2.5

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 (116) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGES.md +7 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +102 -0
  5. data/Rakefile +47 -0
  6. data/VERSION.yml +5 -0
  7. data/culerity.gemspec +165 -0
  8. data/features/fixtures/jquery +4376 -0
  9. data/features/fixtures/sample_feature +14 -0
  10. data/features/installing_culerity.feature +36 -0
  11. data/features/running_cucumber_without_explicitly_running_external_services.feature +23 -0
  12. data/features/step_definitions/common_steps.rb +175 -0
  13. data/features/step_definitions/culerity_setup_steps.rb +7 -0
  14. data/features/step_definitions/jruby_steps.rb +11 -0
  15. data/features/step_definitions/rails_setup_steps.rb +36 -0
  16. data/features/support/common.rb +32 -0
  17. data/features/support/env.rb +24 -0
  18. data/features/support/matchers.rb +11 -0
  19. data/init.rb +1 -0
  20. data/lib/culerity.rb +44 -0
  21. data/lib/culerity/celerity_server.rb +81 -0
  22. data/lib/culerity/jruby_runner.rb +13 -0
  23. data/lib/culerity/remote_browser_proxy.rb +58 -0
  24. data/lib/culerity/remote_object_proxy.rb +76 -0
  25. data/rails/init.rb +1 -0
  26. data/rails_generators/culerity/culerity_generator.rb +28 -0
  27. data/rails_generators/culerity/templates/config/environments/culerity_continuousintegration.rb +28 -0
  28. data/rails_generators/culerity/templates/config/environments/culerity_development.rb +17 -0
  29. data/rails_generators/culerity/templates/features/step_definitions/culerity_steps.rb +109 -0
  30. data/rails_generators/culerity/templates/features/support/env.rb +9 -0
  31. data/rails_generators/culerity/templates/lib/tasks/culerity.rake +38 -0
  32. data/rails_generators/culerity/templates/public/javascripts/culerity.js +27 -0
  33. data/script/console +10 -0
  34. data/script/destroy +14 -0
  35. data/script/generate +14 -0
  36. data/spec/celerity_server_spec.rb +106 -0
  37. data/spec/culerity_spec.rb +33 -0
  38. data/spec/jruby_runner_spec.rb +12 -0
  39. data/spec/remote_browser_proxy_spec.rb +62 -0
  40. data/spec/remote_object_proxy_spec.rb +63 -0
  41. data/spec/spec_helper.rb +3 -0
  42. data/vendor/gems/celerity-0.7.6/HISTORY +111 -0
  43. data/vendor/gems/celerity-0.7.6/LICENSE +621 -0
  44. data/vendor/gems/celerity-0.7.6/README.rdoc +80 -0
  45. data/vendor/gems/celerity-0.7.6/Rakefile +11 -0
  46. data/vendor/gems/celerity-0.7.6/VERSION.yml +5 -0
  47. data/vendor/gems/celerity-0.7.6/celerity.gemspec +120 -0
  48. data/vendor/gems/celerity-0.7.6/lib/celerity.rb +77 -0
  49. data/vendor/gems/celerity-0.7.6/lib/celerity/browser.rb +893 -0
  50. data/vendor/gems/celerity-0.7.6/lib/celerity/clickable_element.rb +73 -0
  51. data/vendor/gems/celerity-0.7.6/lib/celerity/collections.rb +156 -0
  52. data/vendor/gems/celerity-0.7.6/lib/celerity/container.rb +767 -0
  53. data/vendor/gems/celerity-0.7.6/lib/celerity/default_viewer.rb +14 -0
  54. data/vendor/gems/celerity-0.7.6/lib/celerity/disabled_element.rb +40 -0
  55. data/vendor/gems/celerity-0.7.6/lib/celerity/element.rb +298 -0
  56. data/vendor/gems/celerity-0.7.6/lib/celerity/element_collection.rb +107 -0
  57. data/vendor/gems/celerity-0.7.6/lib/celerity/element_locator.rb +159 -0
  58. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/button.rb +54 -0
  59. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/file_field.rb +29 -0
  60. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/form.rb +33 -0
  61. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/frame.rb +86 -0
  62. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/image.rb +89 -0
  63. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/label.rb +16 -0
  64. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/link.rb +43 -0
  65. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/meta.rb +14 -0
  66. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/non_control_elements.rb +116 -0
  67. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/option.rb +38 -0
  68. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/radio_check.rb +114 -0
  69. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/select_list.rb +147 -0
  70. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table.rb +153 -0
  71. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_cell.rb +36 -0
  72. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_elements.rb +42 -0
  73. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_row.rb +49 -0
  74. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/text_field.rb +168 -0
  75. data/vendor/gems/celerity-0.7.6/lib/celerity/exception.rb +83 -0
  76. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit.rb +64 -0
  77. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
  78. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  79. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
  80. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  81. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
  82. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  83. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  84. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-2.7-SNAPSHOT.jar +0 -0
  85. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-core-js-2.7-SNAPSHOT.jar +0 -0
  86. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/nekohtml-1.9.14-20091130.152932-3.jar +0 -0
  87. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  88. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  89. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  90. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
  91. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  92. data/vendor/gems/celerity-0.7.6/lib/celerity/identifier.rb +28 -0
  93. data/vendor/gems/celerity-0.7.6/lib/celerity/ignoring_web_connection.rb +15 -0
  94. data/vendor/gems/celerity-0.7.6/lib/celerity/input_element.rb +25 -0
  95. data/vendor/gems/celerity-0.7.6/lib/celerity/javascript_debugger.rb +32 -0
  96. data/vendor/gems/celerity-0.7.6/lib/celerity/listener.rb +143 -0
  97. data/vendor/gems/celerity-0.7.6/lib/celerity/resources/no_viewer.png +0 -0
  98. data/vendor/gems/celerity-0.7.6/lib/celerity/short_inspect.rb +20 -0
  99. data/vendor/gems/celerity-0.7.6/lib/celerity/util.rb +126 -0
  100. data/vendor/gems/celerity-0.7.6/lib/celerity/version.rb +3 -0
  101. data/vendor/gems/celerity-0.7.6/lib/celerity/viewer_connection.rb +89 -0
  102. data/vendor/gems/celerity-0.7.6/lib/celerity/watir_compatibility.rb +70 -0
  103. data/vendor/gems/celerity-0.7.6/lib/celerity/xpath_support.rb +48 -0
  104. data/vendor/gems/celerity-0.7.6/tasks/benchmark.rake +4 -0
  105. data/vendor/gems/celerity-0.7.6/tasks/check.rake +24 -0
  106. data/vendor/gems/celerity-0.7.6/tasks/clean.rake +3 -0
  107. data/vendor/gems/celerity-0.7.6/tasks/fix.rake +25 -0
  108. data/vendor/gems/celerity-0.7.6/tasks/jar.rake +55 -0
  109. data/vendor/gems/celerity-0.7.6/tasks/jeweler.rake +26 -0
  110. data/vendor/gems/celerity-0.7.6/tasks/rdoc.rake +4 -0
  111. data/vendor/gems/celerity-0.7.6/tasks/snapshot.rake +22 -0
  112. data/vendor/gems/celerity-0.7.6/tasks/spec.rake +26 -0
  113. data/vendor/gems/celerity-0.7.6/tasks/website.rake +10 -0
  114. data/vendor/gems/celerity-0.7.6/tasks/yard.rake +16 -0
  115. data/vendor/jruby/jruby-complete-1.4.0.jar +0 -0
  116. metadata +194 -0
@@ -0,0 +1,14 @@
1
+ module Celerity
2
+ class DefaultViewer
3
+ IMAGE = "#{Celerity::DIR}/resources/no_viewer.png"
4
+
5
+ class << self
6
+ def save(path = nil)
7
+ return unless path
8
+ FileUtils.copy(IMAGE, path)
9
+ end
10
+
11
+ def close; end
12
+ end
13
+ end
14
+ 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,298 @@
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
+ # HTML 4.01 Transitional DTD
14
+ HTML_401_TRANSITIONAL = {
15
+ :core => [:class, :id, :style, :title],
16
+ :cell_halign => [:align, :char, :charoff],
17
+ :cell_valign => [:valign],
18
+ :i18n => [:dir, :lang],
19
+ :event => [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
20
+ :onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup],
21
+ :sloppy => [:name, :value]
22
+ }
23
+
24
+ CELLHALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_halign]
25
+ CELLVALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_valign]
26
+ BASE_ATTRIBUTES = HTML_401_TRANSITIONAL.values_at(:core, :i18n, :event, :sloppy).flatten
27
+ ATTRIBUTES = BASE_ATTRIBUTES
28
+ TAGS = []
29
+
30
+ DEFAULT_HOW = nil
31
+
32
+ # @api private
33
+ def initialize(container, *args)
34
+ self.container = container
35
+
36
+ case args.size
37
+ when 2
38
+ @conditions = { args[0] => args[1] }
39
+ when 1
40
+ if args.first.is_a? Hash
41
+ @conditions = args.first
42
+ elsif (how = self.class::DEFAULT_HOW)
43
+ @conditions = { how => args.first }
44
+ else
45
+ raise ArgumentError, "wrong number of arguments (1 for 2)"
46
+ end
47
+ else
48
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
49
+ end
50
+
51
+ @conditions.freeze
52
+ @object = nil
53
+ end
54
+
55
+ def ==(other)
56
+ return false unless other.kind_of? Element
57
+ xpath == other.xpath
58
+ end
59
+
60
+ #
61
+ # Get the parent element
62
+ # @return [Celerity::Element, nil] subclass of Celerity::Element, or nil if no parent was found
63
+ #
64
+
65
+ def parent
66
+ assert_exists
67
+
68
+ obj = @object.parentNode
69
+ until element_class = Celerity::Util.htmlunit2celerity(obj.class)
70
+ return nil if obj.nil?
71
+ obj = obj.parentNode
72
+ end
73
+
74
+ element_class.new(@container, :object, obj)
75
+ end
76
+
77
+ #
78
+ # Sets the focus to this element.
79
+ #
80
+
81
+ def focus
82
+ assert_exists
83
+ @object.focus
84
+ end
85
+
86
+ #
87
+ # Fires the given event for this element
88
+ #
89
+
90
+ def fire_event(event_name)
91
+ assert_exists
92
+ @object.fireEvent(event_name.sub(/^on/, ''))
93
+ end
94
+
95
+ #
96
+ # Used internally. Find the element on the page.
97
+ # @api private
98
+ #
99
+
100
+ def locate
101
+ @object = ElementLocator.new(@container, self.class).find_by_conditions(@conditions)
102
+ end
103
+
104
+ #
105
+ # Returns the HtmlUnit object backing this element
106
+ #
107
+
108
+ def object
109
+ @object || locate
110
+ end
111
+
112
+ #
113
+ # Returns a JavaScript object representing the receiver
114
+ #
115
+ # @api internal - subject to change
116
+ #
117
+
118
+ def javascript_object
119
+ assert_exists
120
+ @object.getScriptObject
121
+ end
122
+
123
+ #
124
+ # @return [String] A string representation of the element.
125
+ #
126
+
127
+ def to_s
128
+ assert_exists
129
+ Celerity::Util.create_string @object
130
+ end
131
+
132
+ #
133
+ # @param [String, #to_s] The attribute.
134
+ # @return [String] The value of the given attribute.
135
+ #
136
+
137
+ def attribute_value(attribute)
138
+ assert_exists
139
+ @object.getAttribute attribute.to_s
140
+ end
141
+
142
+ #
143
+ # Check if the element is visible to the user or not.
144
+ # Note that this only takes the _style attribute_ of the element (and
145
+ # its parents) into account - styles from applied CSS is not considered.
146
+ #
147
+ # @return [boolean]
148
+ #
149
+
150
+ def visible?
151
+ assert_exists
152
+ @object.isDisplayed
153
+ end
154
+
155
+ #
156
+ # Used internally to ensure the element actually exists.
157
+ #
158
+ # @raise [Celerity::Exception::UnknownObjectException] if the element can't be found.
159
+ # @api private
160
+ #
161
+
162
+ def assert_exists
163
+ locate unless @object
164
+ unless @object
165
+ raise UnknownObjectException, "Unable to locate #{self.class.name[/::(.*)$/, 1]}, using #{identifier_string}"
166
+ end
167
+ end
168
+
169
+ #
170
+ # Checks if the element exists.
171
+ # @return [true, false]
172
+ #
173
+
174
+ def exists?
175
+ assert_exists
176
+ true
177
+ rescue UnknownObjectException, UnknownFrameException
178
+ false
179
+ end
180
+ alias_method :exist?, :exists?
181
+
182
+ #
183
+ # Return a text representation of the element as it would appear in a browser.
184
+ #
185
+ # @see inner_text
186
+ # @return [String]
187
+ #
188
+
189
+ def text
190
+ assert_exists
191
+ @object.asText.strip # this must behave like ElementLocator
192
+ end
193
+
194
+ #
195
+ # Return the text content of this DOM node, disregarding its visibility.
196
+ #
197
+ # (Celerity-specific?)
198
+ #
199
+ # @see text
200
+ # @return [String]
201
+ #
202
+
203
+ def inner_text
204
+ assert_exists
205
+ Celerity::Util.normalize_text @object.getTextContent
206
+ end
207
+
208
+ #
209
+ # @return [String] The normative XML representation of the element (including children).
210
+ #
211
+
212
+ def to_xml
213
+ assert_exists
214
+ @object.asXml
215
+ end
216
+ alias_method :asXml, :to_xml
217
+ alias_method :as_xml, :to_xml
218
+ alias_method :html, :to_xml
219
+
220
+ #
221
+ # @return [String] A string representation of the element's attributes.
222
+ #
223
+
224
+ def attribute_string
225
+ assert_exists
226
+
227
+ result = ''
228
+ @object.getAttributes.each do |attribute|
229
+ result << %Q{#{attribute.getName}="#{attribute.getValue}"}
230
+ end
231
+
232
+ result
233
+ end
234
+
235
+ #
236
+ # return the canonical xpath for this element (Celerity-specific)
237
+ #
238
+
239
+ def xpath
240
+ assert_exists
241
+ @object.getCanonicalXPath
242
+ end
243
+
244
+ #
245
+ # Dynamically get element attributes.
246
+ #
247
+ # @see ATTRIBUTES constant for a list of valid methods for a given element.
248
+ #
249
+ # @return [String] The resulting attribute.
250
+ # @raise [NoMethodError] if the element doesn't support this attribute.
251
+ #
252
+
253
+ def method_missing(meth, *args, &blk)
254
+ assert_exists
255
+
256
+ meth = selector_to_attribute(meth)
257
+
258
+ if self.class::ATTRIBUTES.include?(meth) || (self.class == Element && @object.hasAttribute(meth.to_s))
259
+ return @object.getAttribute(meth.to_s)
260
+ end
261
+ Log.warn "Element\#method_missing calling super with #{meth.inspect}"
262
+ super
263
+ end
264
+
265
+ def methods(*args)
266
+ ms = super
267
+ ms += self.class::ATTRIBUTES.map { |e| e.to_s }
268
+ ms.sort
269
+ end
270
+
271
+ def respond_to?(meth, include_private = false)
272
+ meth = selector_to_attribute(meth)
273
+ return true if self.class::ATTRIBUTES.include?(meth)
274
+ super
275
+ end
276
+
277
+ private
278
+
279
+ def identifier_string
280
+ if @conditions.size == 1
281
+ how, what = @conditions.to_a.first
282
+ "#{how.inspect} and #{what.inspect}"
283
+ else
284
+ @conditions.inspect
285
+ end
286
+ end
287
+
288
+ def selector_to_attribute(meth)
289
+ case meth
290
+ when :class_name then :class
291
+ when :caption then :value
292
+ when :url then :href
293
+ else meth
294
+ end
295
+ end
296
+
297
+ end # Element
298
+ 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 + Celerity.index_offset)
104
+ end
105
+
106
+ end # ElementCollection
107
+ end # Celerity