celerity 0.0.4 → 0.0.6
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.
- data/History.txt +33 -0
- data/README.txt +19 -9
- data/Rakefile +9 -3
- data/lib/celerity.rb +39 -39
- data/lib/celerity/browser.rb +538 -153
- data/lib/celerity/clickable_element.rb +48 -7
- data/lib/celerity/collections.rb +155 -131
- data/lib/celerity/container.rb +766 -385
- data/lib/celerity/default_viewer.rb +10 -0
- data/lib/celerity/disabled_element.rb +19 -2
- data/lib/celerity/element.rb +152 -83
- data/lib/celerity/element_collection.rb +106 -0
- data/lib/celerity/element_locator.rb +89 -66
- data/lib/celerity/elements/button.rb +23 -13
- data/lib/celerity/elements/file_field.rb +17 -5
- data/lib/celerity/elements/form.rb +21 -16
- data/lib/celerity/elements/frame.rb +75 -53
- data/lib/celerity/elements/image.rb +76 -63
- data/lib/celerity/elements/label.rb +4 -2
- data/lib/celerity/elements/link.rb +30 -18
- data/lib/celerity/elements/meta.rb +6 -0
- data/lib/celerity/{non_control_elements.rb → elements/non_control_elements.rb} +106 -76
- data/lib/celerity/elements/option.rb +16 -2
- data/lib/celerity/elements/radio_check.rb +55 -20
- data/lib/celerity/elements/select_list.rb +65 -29
- data/lib/celerity/elements/table.rb +141 -94
- data/lib/celerity/elements/table_cell.rb +13 -6
- data/lib/celerity/elements/{table_body.rb → table_elements.rb} +20 -8
- data/lib/celerity/elements/table_row.rb +23 -7
- data/lib/celerity/elements/text_field.rb +89 -33
- data/lib/celerity/exception.rb +77 -41
- data/lib/celerity/extra/method_generator.rb +42 -24
- data/lib/celerity/htmlunit.rb +49 -0
- data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.5-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.5-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.12-20090308.130127-11.jar +0 -0
- data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
- data/lib/celerity/identifier.rb +3 -2
- data/lib/celerity/input_element.rb +5 -5
- data/lib/celerity/listener.rb +135 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/util.rb +88 -0
- data/lib/celerity/version.rb +4 -3
- data/lib/celerity/watir_compatibility.rb +35 -25
- data/tasks/jar.rake +57 -0
- metadata +35 -142
- data.tar.gz.sig +0 -0
- data/Manifest.txt +0 -150
- data/lib/celerity/element_collections.rb +0 -54
- data/lib/celerity/element_map.rb +0 -51
- data/lib/celerity/elements/table_footer.rb +0 -30
- data/lib/celerity/elements/table_header.rb +0 -30
- data/lib/celerity/htmlunit/commons-collections-3.2.jar +0 -0
- data/lib/celerity/htmlunit/download.sh +0 -23
- data/lib/celerity/htmlunit/htmlunit-2.2.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.2.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.8.jar +0 -0
- data/lib/celerity/htmlunit/xalan-2.7.0.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.0.b2.jar +0 -0
- data/spec/area_spec.rb +0 -97
- data/spec/areas_spec.rb +0 -40
- data/spec/browser_spec.rb +0 -266
- data/spec/button_spec.rb +0 -227
- data/spec/buttons_spec.rb +0 -39
- data/spec/checkbox_spec.rb +0 -302
- data/spec/checkboxes_spec.rb +0 -38
- data/spec/div_spec.rb +0 -207
- data/spec/divs_spec.rb +0 -39
- data/spec/element_spec.rb +0 -79
- data/spec/filefield_spec.rb +0 -123
- data/spec/filefields_spec.rb +0 -40
- data/spec/form_spec.rb +0 -59
- data/spec/forms_spec.rb +0 -41
- data/spec/frame_spec.rb +0 -121
- data/spec/frames_spec.rb +0 -71
- data/spec/hidden_spec.rb +0 -127
- data/spec/hiddens_spec.rb +0 -39
- data/spec/hn_spec.rb +0 -104
- data/spec/hns_spec.rb +0 -45
- data/spec/html/2000_spans.html +0 -2009
- data/spec/html/bug_duplicate_attributes.html +0 -14
- data/spec/html/bug_javascript_001.html +0 -11
- data/spec/html/form_js_bug.html +0 -11
- data/spec/html/forms_with_input_elements.html +0 -114
- data/spec/html/frame_1.html +0 -17
- data/spec/html/frame_2.html +0 -16
- data/spec/html/frames.html +0 -11
- data/spec/html/iframes.html +0 -12
- data/spec/html/images.html +0 -27
- data/spec/html/images/1.gif +0 -0
- data/spec/html/images/2.gif +0 -0
- data/spec/html/images/3.gif +0 -0
- data/spec/html/images/button.jpg +0 -0
- data/spec/html/images/circle.jpg +0 -0
- data/spec/html/images/map.gif +0 -0
- data/spec/html/images/map2.gif +0 -0
- data/spec/html/images/minus.gif +0 -0
- data/spec/html/images/originaltriangle.jpg +0 -0
- data/spec/html/images/plus.gif +0 -0
- data/spec/html/images/square.jpg +0 -0
- data/spec/html/images/triangle.jpg +0 -0
- data/spec/html/invalid_js.html +0 -11
- data/spec/html/latin1_text.html +0 -17
- data/spec/html/non_control_elements.html +0 -115
- data/spec/html/simple_ajax.html +0 -22
- data/spec/html/tables.html +0 -119
- data/spec/html/utf8_text.html +0 -15
- data/spec/htmlunit_spec.rb +0 -26
- data/spec/image_spec.rb +0 -220
- data/spec/images_spec.rb +0 -39
- data/spec/label_spec.rb +0 -79
- data/spec/labels_spec.rb +0 -40
- data/spec/li_spec.rb +0 -139
- data/spec/link_spec.rb +0 -189
- data/spec/links_spec.rb +0 -43
- data/spec/lis_spec.rb +0 -40
- data/spec/map_spec.rb +0 -102
- data/spec/maps_spec.rb +0 -40
- data/spec/meta_spec.rb +0 -8
- data/spec/ol_spec.rb +0 -87
- data/spec/ols_spec.rb +0 -40
- data/spec/option_spec.rb +0 -154
- data/spec/p_spec.rb +0 -171
- data/spec/pre_spec.rb +0 -135
- data/spec/pres_spec.rb +0 -40
- data/spec/ps_spec.rb +0 -40
- data/spec/radio_spec.rb +0 -299
- data/spec/radios_spec.rb +0 -42
- data/spec/select_list_spec.rb +0 -299
- data/spec/select_lists_spec.rb +0 -47
- data/spec/span_spec.rb +0 -184
- data/spec/spans_spec.rb +0 -64
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -55
- data/spec/table_bodies_spec.rb +0 -57
- data/spec/table_body_spec.rb +0 -111
- data/spec/table_cell_spec.rb +0 -74
- data/spec/table_cells_spec.rb +0 -59
- data/spec/table_footer_spec.rb +0 -101
- data/spec/table_footers_spec.rb +0 -55
- data/spec/table_header_spec.rb +0 -101
- data/spec/table_headers_spec.rb +0 -55
- data/spec/table_row_spec.rb +0 -104
- data/spec/table_rows_spec.rb +0 -58
- data/spec/table_spec.rb +0 -160
- data/spec/tables_spec.rb +0 -42
- data/spec/text_field_spec.rb +0 -323
- data/spec/text_fields_spec.rb +0 -44
- data/spec/ul_spec.rb +0 -88
- data/spec/uls_spec.rb +0 -40
- data/spec/watir_compatibility_spec.rb +0 -260
- data/support/spec_server.rb +0 -73
- data/tasks/rspec.rake +0 -30
- data/tasks/specserver.rake +0 -21
- metadata.gz.sig +0 -0
|
@@ -1,23 +1,40 @@
|
|
|
1
1
|
module Celerity
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Mixed in to all elements that can have the 'disabled' attribute.
|
|
5
|
+
#
|
|
6
|
+
|
|
3
7
|
module DisabledElement
|
|
4
8
|
include Celerity::Exception
|
|
5
9
|
|
|
10
|
+
#
|
|
11
|
+
# Returns false if the element is disabled.
|
|
12
|
+
#
|
|
13
|
+
|
|
6
14
|
def enabled?
|
|
7
15
|
!disabled?
|
|
8
16
|
end
|
|
9
17
|
|
|
18
|
+
#
|
|
19
|
+
# Returns true if the element is disabled.
|
|
20
|
+
#
|
|
21
|
+
|
|
10
22
|
def disabled?
|
|
11
23
|
assert_exists unless defined?(@object) && @object
|
|
12
24
|
@object.isDisabled
|
|
13
25
|
end
|
|
14
26
|
alias_method :disabled, :disabled?
|
|
15
27
|
|
|
28
|
+
#
|
|
29
|
+
# Used internally.
|
|
30
|
+
# @api private
|
|
31
|
+
#
|
|
32
|
+
|
|
16
33
|
def assert_enabled
|
|
17
34
|
if disabled?
|
|
18
35
|
raise ObjectDisabledException, "Object #{identifier_string} is disabled"
|
|
19
36
|
end
|
|
20
37
|
end
|
|
21
|
-
|
|
38
|
+
|
|
22
39
|
end
|
|
23
40
|
end
|
data/lib/celerity/element.rb
CHANGED
|
@@ -1,105 +1,151 @@
|
|
|
1
1
|
module Celerity
|
|
2
2
|
|
|
3
|
+
#
|
|
3
4
|
# Superclass for all HTML elements.
|
|
5
|
+
#
|
|
6
|
+
|
|
4
7
|
class Element
|
|
5
8
|
include Exception
|
|
6
9
|
include Container
|
|
7
|
-
|
|
10
|
+
|
|
8
11
|
attr_reader :container, :object
|
|
9
|
-
|
|
12
|
+
|
|
10
13
|
# number of spaces that separate the property from the value in the create_string method
|
|
11
14
|
TO_S_SIZE = 14
|
|
12
|
-
|
|
15
|
+
|
|
13
16
|
# HTML 4.01 Transitional DTD
|
|
14
|
-
HTML_401_TRANSITIONAL = {
|
|
17
|
+
HTML_401_TRANSITIONAL = {
|
|
15
18
|
:core => [:class, :id, :style, :title],
|
|
16
19
|
:cell_halign => [:align, :char, :charoff],
|
|
17
20
|
:cell_valign => [:valign],
|
|
18
21
|
:i18n => [:dir, :lang],
|
|
19
|
-
:event => [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
|
|
22
|
+
:event => [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
|
|
20
23
|
:onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup],
|
|
21
24
|
:sloppy => [:name, :value]
|
|
22
25
|
}
|
|
23
|
-
|
|
26
|
+
|
|
24
27
|
CELLHALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_halign]
|
|
25
28
|
CELLVALIGN_ATTRIBUTES = HTML_401_TRANSITIONAL[:cell_valign]
|
|
26
29
|
BASE_ATTRIBUTES = HTML_401_TRANSITIONAL.values_at(:core, :i18n, :event, :sloppy).flatten
|
|
27
30
|
ATTRIBUTES = BASE_ATTRIBUTES
|
|
31
|
+
TAGS = []
|
|
28
32
|
|
|
29
33
|
DEFAULT_HOW = nil
|
|
30
|
-
|
|
31
|
-
# @api
|
|
34
|
+
|
|
35
|
+
# @api private
|
|
32
36
|
def initialize(container, *args)
|
|
33
37
|
self.container = container
|
|
34
|
-
|
|
38
|
+
|
|
35
39
|
case args.size
|
|
36
40
|
when 2
|
|
37
41
|
@conditions = { args[0] => args[1] }
|
|
38
42
|
when 1
|
|
39
43
|
if args.first.is_a? Hash
|
|
40
44
|
@conditions = args.first
|
|
41
|
-
elsif self.class::DEFAULT_HOW
|
|
42
|
-
@conditions = {
|
|
45
|
+
elsif (how = self.class::DEFAULT_HOW)
|
|
46
|
+
@conditions = { how => args.first }
|
|
43
47
|
else
|
|
44
48
|
raise ArgumentError, "wrong number of arguments (1 for 2)"
|
|
45
49
|
end
|
|
46
50
|
else
|
|
47
51
|
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
|
|
48
52
|
end
|
|
53
|
+
|
|
54
|
+
@conditions.freeze
|
|
49
55
|
end
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
#
|
|
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
|
+
|
|
53
62
|
def parent
|
|
54
63
|
assert_exists
|
|
55
|
-
|
|
56
|
-
obj = @object.
|
|
57
|
-
until element_class =
|
|
64
|
+
|
|
65
|
+
obj = @object.parentNode
|
|
66
|
+
until element_class = Celerity::Util.htmlunit2celerity(obj.class)
|
|
58
67
|
return nil if obj.nil?
|
|
59
68
|
obj = obj.parentNode
|
|
60
69
|
end
|
|
61
|
-
|
|
70
|
+
|
|
62
71
|
element_class.new(@container, :object, obj)
|
|
63
72
|
end
|
|
64
|
-
|
|
73
|
+
|
|
74
|
+
#
|
|
65
75
|
# Sets the focus to this element.
|
|
76
|
+
#
|
|
77
|
+
|
|
66
78
|
def focus
|
|
67
79
|
assert_exists
|
|
68
80
|
@object.focus
|
|
69
81
|
end
|
|
70
|
-
|
|
71
|
-
#
|
|
72
|
-
#
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Used internally. Find the element on the page.
|
|
85
|
+
# @api private
|
|
86
|
+
#
|
|
87
|
+
|
|
73
88
|
def locate
|
|
74
|
-
@object = ElementLocator.new(@container
|
|
89
|
+
@object = ElementLocator.new(@container, self.class).find_by_conditions(@conditions)
|
|
75
90
|
end
|
|
76
|
-
|
|
91
|
+
|
|
92
|
+
#
|
|
77
93
|
# @return [String] A string representation of the element.
|
|
94
|
+
#
|
|
95
|
+
|
|
78
96
|
def to_s
|
|
79
97
|
assert_exists
|
|
80
98
|
create_string(@object)
|
|
81
99
|
end
|
|
82
|
-
|
|
100
|
+
|
|
101
|
+
#
|
|
83
102
|
# @param [String, #to_s] The attribute.
|
|
84
103
|
# @return [String] The value of the given attribute.
|
|
104
|
+
#
|
|
105
|
+
|
|
85
106
|
def attribute_value(attribute)
|
|
86
107
|
assert_exists
|
|
87
108
|
@object.getAttribute(attribute.to_s)
|
|
88
109
|
end
|
|
89
110
|
|
|
90
|
-
#
|
|
111
|
+
#
|
|
112
|
+
# Check if the element is visible to the user or not.
|
|
113
|
+
# Note that this only takes the _style attribute_ of the element (and
|
|
114
|
+
# its parents) into account - styles from applied CSS is not considered.
|
|
115
|
+
#
|
|
116
|
+
# @return [boolean]
|
|
117
|
+
#
|
|
118
|
+
|
|
119
|
+
def visible?
|
|
120
|
+
obj = self
|
|
121
|
+
while obj
|
|
122
|
+
return false if obj.respond_to?(:type) && obj.type == 'hidden'
|
|
123
|
+
return false if obj.style =~ /display\s*:\s*none|visibility\s*:\s*hidden/
|
|
124
|
+
obj = obj.parent
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
return true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
#
|
|
131
|
+
# Used internally to ensure the element actually exists.
|
|
132
|
+
#
|
|
133
|
+
# @raise [Celerity::Exception::UnknownObjectException] if the element can't be found.
|
|
134
|
+
# @api private
|
|
91
135
|
#
|
|
92
|
-
|
|
93
|
-
# @api internal
|
|
136
|
+
|
|
94
137
|
def assert_exists
|
|
95
138
|
locate
|
|
96
139
|
unless @object
|
|
97
|
-
raise UnknownObjectException, "Unable to locate
|
|
140
|
+
raise UnknownObjectException, "Unable to locate #{self.class.name[/::(.*)$/, 1]}, using #{identifier_string}"
|
|
98
141
|
end
|
|
99
142
|
end
|
|
100
|
-
|
|
143
|
+
|
|
144
|
+
#
|
|
101
145
|
# Checks if the element exists.
|
|
102
146
|
# @return [true, false]
|
|
147
|
+
#
|
|
148
|
+
|
|
103
149
|
def exists?
|
|
104
150
|
assert_exists
|
|
105
151
|
true
|
|
@@ -107,39 +153,37 @@ module Celerity
|
|
|
107
153
|
false
|
|
108
154
|
end
|
|
109
155
|
alias_method :exist?, :exists?
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
# Return a text representation of the element.
|
|
156
|
+
|
|
157
|
+
#
|
|
158
|
+
# Return a text representation of the element as it would appear in a browser.
|
|
159
|
+
#
|
|
160
|
+
# @see inner_text
|
|
113
161
|
# @return [String]
|
|
162
|
+
#
|
|
163
|
+
|
|
114
164
|
def text
|
|
115
165
|
assert_exists
|
|
116
|
-
|
|
117
|
-
# this could work, but breaks some tests atm
|
|
118
|
-
# @object.getTextContent.strip
|
|
119
|
-
|
|
120
|
-
@object.asText.strip
|
|
166
|
+
@object.asText.strip # this must behave like ElementLocator
|
|
121
167
|
end
|
|
122
|
-
alias_method :innerText, :text
|
|
123
|
-
alias_method :inner_text, :text
|
|
124
168
|
|
|
125
|
-
# Check if the element contains the given text.
|
|
126
169
|
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
129
|
-
|
|
170
|
+
# Return the text content of this DOM node, disregarding its visibility.
|
|
171
|
+
#
|
|
172
|
+
# (Celerity-specific?)
|
|
173
|
+
#
|
|
174
|
+
# @see text
|
|
175
|
+
# @return [String]
|
|
176
|
+
#
|
|
177
|
+
|
|
178
|
+
def inner_text
|
|
130
179
|
assert_exists
|
|
131
|
-
|
|
132
|
-
case expected_text
|
|
133
|
-
when Regexp
|
|
134
|
-
text() =~ expected_text
|
|
135
|
-
when String
|
|
136
|
-
text().index(expected_text)
|
|
137
|
-
else
|
|
138
|
-
raise ArgumentError, "Argument #{expected_text.inspect} should be a String or Regexp."
|
|
139
|
-
end
|
|
180
|
+
Celerity::Util.normalize_text @object.getTextContent
|
|
140
181
|
end
|
|
141
182
|
|
|
183
|
+
#
|
|
142
184
|
# @return [String] The normative XML representation of the element (including children).
|
|
185
|
+
#
|
|
186
|
+
|
|
143
187
|
def to_xml
|
|
144
188
|
assert_exists
|
|
145
189
|
@object.asXml
|
|
@@ -147,35 +191,57 @@ module Celerity
|
|
|
147
191
|
alias_method :asXml, :to_xml
|
|
148
192
|
alias_method :as_xml, :to_xml
|
|
149
193
|
alias_method :html, :to_xml
|
|
150
|
-
|
|
194
|
+
|
|
195
|
+
#
|
|
151
196
|
# @return [String] A string representation of the element's attributes.
|
|
197
|
+
#
|
|
198
|
+
|
|
152
199
|
def attribute_string
|
|
153
200
|
assert_exists
|
|
154
|
-
|
|
201
|
+
|
|
155
202
|
result = ''
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
while iterator.hasNext
|
|
159
|
-
attribute = iterator.next
|
|
160
|
-
result << "#{attribute.getName}=\"#{attribute.getHtmlValue.to_s}\" "
|
|
203
|
+
@object.getAttributes.each do |attribute|
|
|
204
|
+
result << %Q{#{attribute.getName}="#{attribute.getHtmlValue}"}
|
|
161
205
|
end
|
|
162
|
-
|
|
206
|
+
|
|
163
207
|
result
|
|
164
208
|
end
|
|
165
209
|
|
|
210
|
+
#
|
|
211
|
+
# return the canonical xpath for this element (Celerity-specific)
|
|
212
|
+
#
|
|
213
|
+
|
|
214
|
+
def xpath
|
|
215
|
+
assert_exists
|
|
216
|
+
@object.getCanonicalXPath
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
#
|
|
166
220
|
# Dynamically get element attributes.
|
|
221
|
+
#
|
|
222
|
+
# @see ATTRIBUTES constant for a list of valid methods for a given element.
|
|
223
|
+
#
|
|
167
224
|
# @return [String] The resulting attribute.
|
|
168
|
-
# @raise
|
|
225
|
+
# @raise [NoMethodError] if the element doesn't support this attribute.
|
|
226
|
+
#
|
|
227
|
+
|
|
169
228
|
def method_missing(meth, *args, &blk)
|
|
229
|
+
assert_exists
|
|
230
|
+
|
|
170
231
|
meth = selector_to_attribute(meth)
|
|
171
|
-
|
|
232
|
+
|
|
172
233
|
if self.class::ATTRIBUTES.include?(meth)
|
|
173
|
-
|
|
174
|
-
@object.getAttributeValue(meth.to_s)
|
|
175
|
-
else
|
|
176
|
-
Log.warn "Element\#method_missing calling super with #{meth.inspect}"
|
|
177
|
-
super
|
|
234
|
+
return @object.getAttributeValue(meth.to_s)
|
|
178
235
|
end
|
|
236
|
+
|
|
237
|
+
Log.warn "Element\#method_missing calling super with #{meth.inspect}"
|
|
238
|
+
super
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def methods(*args)
|
|
242
|
+
ms = super
|
|
243
|
+
ms += self.class::ATTRIBUTES.map { |e| e.to_s }
|
|
244
|
+
ms.sort
|
|
179
245
|
end
|
|
180
246
|
|
|
181
247
|
def respond_to?(meth, include_private = false)
|
|
@@ -185,39 +251,42 @@ module Celerity
|
|
|
185
251
|
end
|
|
186
252
|
|
|
187
253
|
private
|
|
188
|
-
|
|
254
|
+
|
|
189
255
|
def create_string(element)
|
|
190
256
|
ret = []
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
257
|
+
|
|
258
|
+
unless (tag = element.getTagName).empty?
|
|
259
|
+
ret << "tag:".ljust(TO_S_SIZE) + tag
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
element.getAttributes.each do |attribute|
|
|
196
263
|
ret << " #{attribute.getName}:".ljust(TO_S_SIZE+2) + attribute.getHtmlValue.to_s
|
|
197
264
|
end
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
265
|
+
|
|
266
|
+
unless (text = element.asText).empty?
|
|
267
|
+
ret << " text:".ljust(TO_S_SIZE+2) + element.asText
|
|
268
|
+
end
|
|
269
|
+
|
|
201
270
|
ret.join("\n")
|
|
202
271
|
end
|
|
203
|
-
|
|
272
|
+
|
|
204
273
|
def identifier_string
|
|
205
274
|
if @conditions.size == 1
|
|
206
|
-
how, what = @conditions.
|
|
275
|
+
how, what = @conditions.to_a.first
|
|
207
276
|
"#{how.inspect} and #{what.inspect}"
|
|
208
277
|
else
|
|
209
278
|
@conditions.inspect
|
|
210
279
|
end
|
|
211
280
|
end
|
|
212
|
-
|
|
281
|
+
|
|
213
282
|
def selector_to_attribute(meth)
|
|
214
283
|
case meth
|
|
215
284
|
when :class_name then :class
|
|
216
|
-
when :caption
|
|
217
|
-
when :url
|
|
285
|
+
when :caption then :value
|
|
286
|
+
when :url then :href
|
|
218
287
|
else meth
|
|
219
288
|
end
|
|
220
289
|
end
|
|
221
|
-
|
|
290
|
+
|
|
222
291
|
end # Element
|
|
223
292
|
end # Celerity
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
# This is 1-indexed to keep compatibility with Watir - subject to change.
|
|
52
|
+
# Also note that because of Watir's lazy loading, this will return an Element
|
|
53
|
+
# instance even if the index is out of bounds.
|
|
54
|
+
#
|
|
55
|
+
# @param [Fixnum] n Index of wanted element, 1-indexed.
|
|
56
|
+
# @return [Celerity::Element] Returns a subclass of Celerity::Element
|
|
57
|
+
#
|
|
58
|
+
|
|
59
|
+
def [](n)
|
|
60
|
+
if @elements && @elements[n - INDEX_OFFSET]
|
|
61
|
+
element_class.new(@container, :object, @elements[n - INDEX_OFFSET])
|
|
62
|
+
else
|
|
63
|
+
iterator_object(n - INDEX_OFFSET)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Get the first element in this collection. (Celerity-specific)
|
|
69
|
+
#
|
|
70
|
+
# @return [Celerity::Element] Returns a subclass of Celerity::Element
|
|
71
|
+
#
|
|
72
|
+
|
|
73
|
+
def first
|
|
74
|
+
self[INDEX_OFFSET]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Get the last element in this collection. (Celerity-specific)
|
|
79
|
+
#
|
|
80
|
+
# @return [Celerity::Element] Returns a subclass of Celerity::Element
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
def last
|
|
84
|
+
self[INDEX_OFFSET - 1]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#
|
|
88
|
+
# Note: This can be quite useful in irb:
|
|
89
|
+
#
|
|
90
|
+
# puts browser.text_fields
|
|
91
|
+
#
|
|
92
|
+
# @return [String] A string representation of all elements in this collection.
|
|
93
|
+
#
|
|
94
|
+
|
|
95
|
+
def to_s
|
|
96
|
+
map { |e| e.to_s }.join("\n")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def iterator_object(i)
|
|
102
|
+
element_class.new(@container, :index, i+1)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end # ElementCollection
|
|
106
|
+
end # Celerity
|