fletcherm-culerity 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGES.md +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +102 -0
- data/Rakefile +47 -0
- data/VERSION.yml +5 -0
- data/culerity.gemspec +165 -0
- data/features/fixtures/jquery +4376 -0
- data/features/fixtures/sample_feature +14 -0
- data/features/installing_culerity.feature +36 -0
- data/features/running_cucumber_without_explicitly_running_external_services.feature +23 -0
- data/features/step_definitions/common_steps.rb +175 -0
- data/features/step_definitions/culerity_setup_steps.rb +7 -0
- data/features/step_definitions/jruby_steps.rb +11 -0
- data/features/step_definitions/rails_setup_steps.rb +36 -0
- data/features/support/common.rb +32 -0
- data/features/support/env.rb +24 -0
- data/features/support/matchers.rb +11 -0
- data/init.rb +1 -0
- data/lib/culerity.rb +44 -0
- data/lib/culerity/celerity_server.rb +81 -0
- data/lib/culerity/jruby_runner.rb +13 -0
- data/lib/culerity/remote_browser_proxy.rb +58 -0
- data/lib/culerity/remote_object_proxy.rb +76 -0
- data/rails/init.rb +1 -0
- data/rails_generators/culerity/culerity_generator.rb +28 -0
- data/rails_generators/culerity/templates/config/environments/culerity_continuousintegration.rb +28 -0
- data/rails_generators/culerity/templates/config/environments/culerity_development.rb +17 -0
- data/rails_generators/culerity/templates/features/step_definitions/culerity_steps.rb +109 -0
- data/rails_generators/culerity/templates/features/support/env.rb +9 -0
- data/rails_generators/culerity/templates/lib/tasks/culerity.rake +38 -0
- data/rails_generators/culerity/templates/public/javascripts/culerity.js +27 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/celerity_server_spec.rb +106 -0
- data/spec/culerity_spec.rb +33 -0
- data/spec/jruby_runner_spec.rb +12 -0
- data/spec/remote_browser_proxy_spec.rb +62 -0
- data/spec/remote_object_proxy_spec.rb +63 -0
- data/spec/spec_helper.rb +3 -0
- data/vendor/gems/celerity-0.7.6/HISTORY +111 -0
- data/vendor/gems/celerity-0.7.6/LICENSE +621 -0
- data/vendor/gems/celerity-0.7.6/README.rdoc +80 -0
- data/vendor/gems/celerity-0.7.6/Rakefile +11 -0
- data/vendor/gems/celerity-0.7.6/VERSION.yml +5 -0
- data/vendor/gems/celerity-0.7.6/celerity.gemspec +120 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity.rb +77 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/browser.rb +893 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/clickable_element.rb +73 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/collections.rb +156 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/container.rb +767 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/default_viewer.rb +14 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/disabled_element.rb +40 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/element.rb +298 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/element_collection.rb +107 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/element_locator.rb +159 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/button.rb +54 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/file_field.rb +29 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/form.rb +33 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/frame.rb +86 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/image.rb +89 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/label.rb +16 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/link.rb +43 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/meta.rb +14 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/non_control_elements.rb +116 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/option.rb +38 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/radio_check.rb +114 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/select_list.rb +147 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table.rb +153 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_cell.rb +36 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_elements.rb +42 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_row.rb +49 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/elements/text_field.rb +168 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/exception.rb +83 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit.rb +64 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-2.7-SNAPSHOT.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-core-js-2.7-SNAPSHOT.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/nekohtml-1.9.14-20091130.152932-3.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/sac-1.3.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/identifier.rb +28 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/ignoring_web_connection.rb +15 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/input_element.rb +25 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/javascript_debugger.rb +32 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/listener.rb +143 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/resources/no_viewer.png +0 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/short_inspect.rb +20 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/util.rb +126 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/version.rb +3 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/viewer_connection.rb +89 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/watir_compatibility.rb +70 -0
- data/vendor/gems/celerity-0.7.6/lib/celerity/xpath_support.rb +48 -0
- data/vendor/gems/celerity-0.7.6/tasks/benchmark.rake +4 -0
- data/vendor/gems/celerity-0.7.6/tasks/check.rake +24 -0
- data/vendor/gems/celerity-0.7.6/tasks/clean.rake +3 -0
- data/vendor/gems/celerity-0.7.6/tasks/fix.rake +25 -0
- data/vendor/gems/celerity-0.7.6/tasks/jar.rake +55 -0
- data/vendor/gems/celerity-0.7.6/tasks/jeweler.rake +26 -0
- data/vendor/gems/celerity-0.7.6/tasks/rdoc.rake +4 -0
- data/vendor/gems/celerity-0.7.6/tasks/snapshot.rake +22 -0
- data/vendor/gems/celerity-0.7.6/tasks/spec.rake +26 -0
- data/vendor/gems/celerity-0.7.6/tasks/website.rake +10 -0
- data/vendor/gems/celerity-0.7.6/tasks/yard.rake +16 -0
- data/vendor/jruby/jruby-complete-1.4.0.jar +0 -0
- metadata +194 -0
@@ -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
|