jarib-celerity 0.0.5.5 → 0.0.5.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/lib/celerity/browser.rb +220 -83
- data/lib/celerity/collections.rb +39 -39
- data/lib/celerity/container.rb +272 -20
- data/lib/celerity/disabled_element.rb +16 -3
- data/lib/celerity/element.rb +48 -3
- data/lib/celerity/element_locator.rb +3 -0
- data/lib/celerity/elements/button.rb +16 -6
- data/lib/celerity/elements/file_field.rb +10 -2
- data/lib/celerity/elements/form.rb +7 -2
- data/lib/celerity/elements/frame.rb +25 -4
- data/lib/celerity/elements/image.rb +22 -3
- data/lib/celerity/elements/non_control_elements.rb +6 -1
- data/lib/celerity/elements/option.rb +9 -1
- data/lib/celerity/elements/radio_check.rb +44 -14
- data/lib/celerity/elements/select_list.rb +29 -5
- data/lib/celerity/elements/table.rb +30 -7
- data/lib/celerity/elements/table_cell.rb +2 -2
- data/lib/celerity/elements/table_row.rb +14 -3
- data/lib/celerity/elements/text_field.rb +46 -9
- data/lib/celerity/exception.rb +43 -6
- data/lib/celerity/extra/method_generator.rb +13 -1
- data/lib/celerity/htmlunit.rb +6 -1
- data/lib/celerity/listener.rb +37 -8
- data/lib/celerity/util.rb +3 -0
- data/lib/celerity/version.rb +1 -1
- data/lib/celerity/watir_compatibility.rb +12 -11
- data/lib/celerity.rb +1 -1
- metadata +4 -3
- data/lib/celerity/element_collections.rb +0 -82
@@ -1,22 +1,35 @@
|
|
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
|
+
#
|
6
11
|
# Returns false if the element is disabled.
|
12
|
+
#
|
13
|
+
|
7
14
|
def enabled?
|
8
15
|
!disabled?
|
9
16
|
end
|
10
17
|
|
18
|
+
#
|
11
19
|
# Returns true if the element is disabled.
|
20
|
+
#
|
21
|
+
|
12
22
|
def disabled?
|
13
23
|
assert_exists unless defined?(@object) && @object
|
14
24
|
@object.isDisabled
|
15
25
|
end
|
16
26
|
alias_method :disabled, :disabled?
|
17
|
-
|
27
|
+
|
28
|
+
#
|
18
29
|
# Used internally.
|
19
30
|
# @api private
|
31
|
+
#
|
32
|
+
|
20
33
|
def assert_enabled
|
21
34
|
if disabled?
|
22
35
|
raise ObjectDisabledException, "Object #{identifier_string} is disabled"
|
data/lib/celerity/element.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
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
|
@@ -51,8 +54,11 @@ module Celerity
|
|
51
54
|
@conditions.freeze
|
52
55
|
end
|
53
56
|
|
57
|
+
#
|
54
58
|
# Get the parent element
|
55
59
|
# @return [Celerity::Element, nil] subclass of Celerity::Element, or nil if no parent was found
|
60
|
+
#
|
61
|
+
|
56
62
|
def parent
|
57
63
|
assert_exists
|
58
64
|
|
@@ -65,36 +71,51 @@ module Celerity
|
|
65
71
|
element_class.new(@container, :object, obj)
|
66
72
|
end
|
67
73
|
|
74
|
+
#
|
68
75
|
# Sets the focus to this element.
|
76
|
+
#
|
77
|
+
|
69
78
|
def focus
|
70
79
|
assert_exists
|
71
80
|
@object.focus
|
72
81
|
end
|
73
82
|
|
83
|
+
#
|
74
84
|
# Used internally. Find the element on the page.
|
75
85
|
# @api private
|
86
|
+
#
|
87
|
+
|
76
88
|
def locate
|
77
89
|
@object = ElementLocator.new(@container, self.class).find_by_conditions(@conditions)
|
78
90
|
end
|
79
91
|
|
92
|
+
#
|
80
93
|
# @return [String] A string representation of the element.
|
94
|
+
#
|
95
|
+
|
81
96
|
def to_s
|
82
97
|
assert_exists
|
83
98
|
create_string(@object)
|
84
99
|
end
|
85
100
|
|
101
|
+
#
|
86
102
|
# @param [String, #to_s] The attribute.
|
87
103
|
# @return [String] The value of the given attribute.
|
104
|
+
#
|
105
|
+
|
88
106
|
def attribute_value(attribute)
|
89
107
|
assert_exists
|
90
108
|
@object.getAttribute(attribute.to_s)
|
91
109
|
end
|
92
110
|
|
111
|
+
#
|
93
112
|
# Check if the element is visible to the user or not.
|
94
113
|
# Note that this only takes the _style attribute_ of the element (and
|
95
114
|
# its parents) into account - styles from applied CSS is not considered.
|
96
115
|
#
|
97
116
|
# @return [boolean]
|
117
|
+
#
|
118
|
+
|
98
119
|
def visible?
|
99
120
|
obj = self
|
100
121
|
while obj
|
@@ -106,19 +127,25 @@ module Celerity
|
|
106
127
|
return true
|
107
128
|
end
|
108
129
|
|
130
|
+
#
|
109
131
|
# Used internally to ensure the element actually exists.
|
110
132
|
#
|
111
133
|
# @raise [Celerity::Exception::UnknownObjectException] if the element can't be found.
|
112
134
|
# @api private
|
135
|
+
#
|
136
|
+
|
113
137
|
def assert_exists
|
114
138
|
locate
|
115
139
|
unless @object
|
116
140
|
raise UnknownObjectException, "Unable to locate #{self.class.name[/::(.*)$/, 1]}, using #{identifier_string}"
|
117
141
|
end
|
118
142
|
end
|
119
|
-
|
143
|
+
|
144
|
+
#
|
120
145
|
# Checks if the element exists.
|
121
146
|
# @return [true, false]
|
147
|
+
#
|
148
|
+
|
122
149
|
def exists?
|
123
150
|
assert_exists
|
124
151
|
true
|
@@ -126,28 +153,37 @@ module Celerity
|
|
126
153
|
false
|
127
154
|
end
|
128
155
|
alias_method :exist?, :exists?
|
129
|
-
|
156
|
+
|
157
|
+
#
|
130
158
|
# Return a text representation of the element as it would appear in a browser.
|
131
159
|
#
|
132
160
|
# @see inner_text
|
133
161
|
# @return [String]
|
162
|
+
#
|
163
|
+
|
134
164
|
def text
|
135
165
|
assert_exists
|
136
166
|
@object.asText.strip # this must behave like ElementLocator
|
137
167
|
end
|
138
168
|
|
169
|
+
#
|
139
170
|
# Return the text content of this DOM node, disregarding its visibility.
|
140
171
|
#
|
141
172
|
# (Celerity-specific?)
|
142
173
|
#
|
143
174
|
# @see text
|
144
175
|
# @return [String]
|
176
|
+
#
|
177
|
+
|
145
178
|
def inner_text
|
146
179
|
assert_exists
|
147
180
|
Celerity::Util.normalize_text @object.getTextContent
|
148
181
|
end
|
149
182
|
|
183
|
+
#
|
150
184
|
# @return [String] The normative XML representation of the element (including children).
|
185
|
+
#
|
186
|
+
|
151
187
|
def to_xml
|
152
188
|
assert_exists
|
153
189
|
@object.asXml
|
@@ -156,7 +192,10 @@ module Celerity
|
|
156
192
|
alias_method :as_xml, :to_xml
|
157
193
|
alias_method :html, :to_xml
|
158
194
|
|
195
|
+
#
|
159
196
|
# @return [String] A string representation of the element's attributes.
|
197
|
+
#
|
198
|
+
|
160
199
|
def attribute_string
|
161
200
|
assert_exists
|
162
201
|
|
@@ -168,18 +207,24 @@ module Celerity
|
|
168
207
|
result
|
169
208
|
end
|
170
209
|
|
210
|
+
#
|
171
211
|
# return the canonical xpath for this element (Celerity-specific)
|
212
|
+
#
|
213
|
+
|
172
214
|
def xpath
|
173
215
|
assert_exists
|
174
216
|
@object.getCanonicalXPath
|
175
217
|
end
|
176
218
|
|
219
|
+
#
|
177
220
|
# Dynamically get element attributes.
|
178
221
|
#
|
179
222
|
# @see ATTRIBUTES constant for a list of valid methods for a given element.
|
180
223
|
#
|
181
224
|
# @return [String] The resulting attribute.
|
182
225
|
# @raise [NoMethodError] if the element doesn't support this attribute.
|
226
|
+
#
|
227
|
+
|
183
228
|
def method_missing(meth, *args, &blk)
|
184
229
|
assert_exists
|
185
230
|
|
@@ -1,26 +1,36 @@
|
|
1
1
|
module Celerity
|
2
|
+
|
2
3
|
#
|
3
4
|
# Input: Button
|
4
5
|
#
|
5
6
|
# Class representing button elements
|
6
7
|
#
|
8
|
+
|
7
9
|
class Button < InputElement
|
8
10
|
TAGS = [ Identifier.new('button'),
|
9
11
|
Identifier.new('input', :type => %w[submit reset image button]) ]
|
10
|
-
|
12
|
+
|
13
|
+
# Attribute list is a little weird due to this class covering both <button>
|
14
|
+
# and <input type="submit|reset|image|button" />
|
11
15
|
ATTRIBUTES = BASE_ATTRIBUTES | [:type, :disabled, :tabindex, :accesskey, :onfocus, :onblur] | [:src, :usemap, :ismap]
|
12
16
|
DEFAULT_HOW = :value
|
13
17
|
|
18
|
+
#
|
14
19
|
# @api private
|
20
|
+
#
|
21
|
+
|
15
22
|
def locate
|
16
|
-
#
|
17
|
-
#
|
23
|
+
# We want the :value attribute to point to the inner HTML for <button> elements,
|
24
|
+
# and to the value attribute for <input type="button"> elements.
|
25
|
+
|
18
26
|
if (val = @conditions[:value])
|
19
|
-
|
20
|
-
button_ident = Identifier.new('button')
|
27
|
+
button_ident = Identifier.new('button')
|
21
28
|
button_ident.text = val
|
22
|
-
input_ident
|
29
|
+
input_ident = Identifier.new('input', :type => %w[submit reset image button], :value => [val])
|
30
|
+
|
31
|
+
locator = ElementLocator.new(@container, self.class)
|
23
32
|
locator.idents = [button_ident, input_ident]
|
33
|
+
|
24
34
|
conditions = @conditions.dup
|
25
35
|
conditions.delete(:value)
|
26
36
|
@object = locator.find_by_conditions(conditions)
|
@@ -1,10 +1,17 @@
|
|
1
1
|
module Celerity
|
2
|
+
|
3
|
+
#
|
2
4
|
# For fields that accept file uploads
|
5
|
+
#
|
6
|
+
|
3
7
|
class FileField < InputElement
|
4
8
|
TAGS = [ Identifier.new('input', :type => %w[file]) ]
|
5
9
|
DEFAULT_HOW = :name
|
6
10
|
|
11
|
+
#
|
7
12
|
# Set the file field to the given path
|
13
|
+
#
|
14
|
+
|
8
15
|
def set(path)
|
9
16
|
assert_exists
|
10
17
|
path = path.to_s
|
@@ -13,5 +20,6 @@ module Celerity
|
|
13
20
|
@object.setContentType(Celerity::Util.content_type_for(path))
|
14
21
|
end
|
15
22
|
end
|
16
|
-
|
17
|
-
end
|
23
|
+
|
24
|
+
end # FileField
|
25
|
+
end # Celerity
|
@@ -1,16 +1,21 @@
|
|
1
1
|
module Celerity
|
2
2
|
class Form < Element
|
3
3
|
include Container
|
4
|
+
|
4
5
|
TAGS = [Identifier.new('form')]
|
6
|
+
|
5
7
|
# HTML 4.01 Transitional DTD
|
6
8
|
ATTRIBUTES = BASE_ATTRIBUTES | [:action, :method, :enctype, :accept, :name, :onsubmit, :onreset, :target, :'accept-charset']
|
7
9
|
DEFAULT_HOW = :name
|
8
10
|
|
11
|
+
#
|
9
12
|
# Submits the form.
|
13
|
+
#
|
14
|
+
|
10
15
|
def submit
|
11
16
|
assert_exists
|
12
17
|
@container.update_page @object.submit(nil)
|
13
18
|
end
|
14
19
|
|
15
|
-
end
|
16
|
-
end
|
20
|
+
end # Form
|
21
|
+
end # Celerity
|
@@ -7,8 +7,11 @@ module Celerity
|
|
7
7
|
ATTRIBUTES = BASE_ATTRIBUTES | [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
|
8
8
|
DEFAULT_HOW = :name
|
9
9
|
|
10
|
+
#
|
10
11
|
# Override the default locate to handle frame and inline frames.
|
11
12
|
# @api private
|
13
|
+
#
|
14
|
+
|
12
15
|
def locate
|
13
16
|
super
|
14
17
|
if @object
|
@@ -19,9 +22,12 @@ module Celerity
|
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
22
|
-
|
25
|
+
|
26
|
+
#
|
23
27
|
# Override assert_exists to raise UnknownFrameException (for Watir compatibility)
|
24
28
|
# @api private
|
29
|
+
#
|
30
|
+
|
25
31
|
def assert_exists
|
26
32
|
locate
|
27
33
|
unless @object
|
@@ -29,6 +35,22 @@ module Celerity
|
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
38
|
+
#
|
39
|
+
# Executes the given JavaScript string in this frame. (Celerity only)
|
40
|
+
#
|
41
|
+
|
42
|
+
def execute_script(source)
|
43
|
+
assert_exists
|
44
|
+
@page.executeJavaScript(source.to_s).getJavaScriptResult
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Updates the brwoser page with the page from this frame's top window.
|
49
|
+
# Used internally.
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
#
|
53
|
+
|
32
54
|
def update_page(value)
|
33
55
|
@browser.page = value.getEnclosingWindow.getTopWindow.getEnclosedPage
|
34
56
|
end
|
@@ -49,6 +71,5 @@ module Celerity
|
|
49
71
|
end
|
50
72
|
end
|
51
73
|
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
74
|
+
end # Frame
|
75
|
+
end # Celerity
|
@@ -4,36 +4,52 @@ module Celerity
|
|
4
4
|
include ClickableElement
|
5
5
|
|
6
6
|
TAGS = [ Identifier.new('img') ]
|
7
|
+
|
7
8
|
ATTRIBUTES = BASE_ATTRIBUTES | [:src, :alt, :longdesc, :name, :height, :width, :usemap, :ismap, :align, :border, :hspace, :vspace]
|
8
9
|
DEFAULT_HOW = :src
|
9
10
|
|
11
|
+
#
|
10
12
|
# returns the file created date of the image
|
13
|
+
#
|
14
|
+
|
11
15
|
def file_created_date
|
12
16
|
assert_exists
|
13
17
|
web_response = @object.getWebResponse(true)
|
14
18
|
Time.parse(web_response.getResponseHeaderValue("Last-Modified").to_s)
|
15
19
|
end
|
16
20
|
|
21
|
+
#
|
17
22
|
# returns the filesize of the image
|
23
|
+
#
|
24
|
+
|
18
25
|
def file_size
|
19
26
|
assert_exists
|
20
27
|
web_response = @object.getWebResponse(true)
|
21
28
|
web_response.getResponseBody.length
|
22
29
|
end
|
23
30
|
|
31
|
+
#
|
24
32
|
# returns the width in pixels of the image, as a string
|
33
|
+
#
|
34
|
+
|
25
35
|
def width
|
26
36
|
assert_exists
|
27
37
|
@object.getWidth
|
28
38
|
end
|
29
39
|
|
40
|
+
#
|
30
41
|
# returns the height in pixels of the image, as a string
|
42
|
+
#
|
43
|
+
|
31
44
|
def height
|
32
45
|
assert_exists
|
33
46
|
@object.getHeight
|
34
47
|
end
|
35
48
|
|
49
|
+
#
|
36
50
|
# returns true if the image is loaded
|
51
|
+
#
|
52
|
+
|
37
53
|
def loaded?
|
38
54
|
assert_exists
|
39
55
|
begin
|
@@ -44,7 +60,10 @@ module Celerity
|
|
44
60
|
end
|
45
61
|
end
|
46
62
|
|
63
|
+
#
|
47
64
|
# Saves the image to the given file
|
65
|
+
#
|
66
|
+
|
48
67
|
def save(filename)
|
49
68
|
assert_exists
|
50
69
|
image_reader = @object.getImageReader
|
@@ -52,6 +71,6 @@ module Celerity
|
|
52
71
|
buffered_image = image_reader.read(0);
|
53
72
|
javax.imageio.ImageIO.write(buffered_image, image_reader.getFormatName(), file);
|
54
73
|
end
|
55
|
-
|
56
|
-
|
57
|
-
end
|
74
|
+
|
75
|
+
end # Image
|
76
|
+
end # Celerity
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module Celerity
|
2
|
-
|
2
|
+
|
3
|
+
#
|
3
4
|
# Superclass for for Span, Pre, Div, H1, ...
|
5
|
+
#
|
6
|
+
|
4
7
|
class NonControlElement < Element
|
5
8
|
include Exception
|
6
9
|
include ClickableElement
|
@@ -10,7 +13,9 @@ module Celerity
|
|
10
13
|
end
|
11
14
|
|
12
15
|
#
|
16
|
+
#--
|
13
17
|
# classes ordered alphabetically
|
18
|
+
#++
|
14
19
|
#
|
15
20
|
|
16
21
|
class Area < NonControlElement
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module Celerity
|
2
|
-
|
2
|
+
|
3
|
+
#
|
4
|
+
# Represents an option in a select list.
|
5
|
+
#
|
6
|
+
|
3
7
|
class Option < Element
|
4
8
|
include ClickableElement
|
5
9
|
include DisabledElement
|
@@ -10,6 +14,10 @@ module Celerity
|
|
10
14
|
|
11
15
|
alias_method :select, :click
|
12
16
|
|
17
|
+
#
|
18
|
+
# Is this option selected?
|
19
|
+
#
|
20
|
+
|
13
21
|
def selected?
|
14
22
|
assert_exists
|
15
23
|
@object.isSelected
|
@@ -1,10 +1,16 @@
|
|
1
1
|
module Celerity
|
2
|
+
|
3
|
+
#
|
2
4
|
# Common superclass for radios and check boxes.
|
5
|
+
#
|
6
|
+
|
3
7
|
class RadioCheckCommon < InputElement
|
4
8
|
DEFAULT_HOW = :name
|
5
|
-
|
6
|
-
#
|
7
|
-
#
|
9
|
+
|
10
|
+
#
|
11
|
+
# Can optionally take a value parameter as a third arg, so we override initialize
|
12
|
+
#
|
13
|
+
|
8
14
|
def initialize(container, type, *args)
|
9
15
|
@type = type
|
10
16
|
case args.size
|
@@ -16,36 +22,52 @@ module Celerity
|
|
16
22
|
super(container, *args)
|
17
23
|
end
|
18
24
|
end
|
19
|
-
|
25
|
+
|
26
|
+
#
|
20
27
|
# returns true if the element is checked
|
21
28
|
# @return [true, false]
|
29
|
+
#
|
30
|
+
|
22
31
|
def set?
|
23
32
|
assert_exists
|
24
33
|
@object.isChecked
|
25
34
|
end
|
26
35
|
alias_method :checked?, :set?
|
27
36
|
|
37
|
+
#
|
38
|
+
# Unset this element.
|
39
|
+
#
|
40
|
+
|
28
41
|
def clear
|
29
42
|
set(false)
|
30
43
|
end
|
31
44
|
end
|
32
45
|
|
33
|
-
#
|
46
|
+
#
|
47
|
+
# This class is the representation of a radio button.
|
48
|
+
#
|
49
|
+
|
34
50
|
class Radio < RadioCheckCommon
|
35
51
|
TAGS = [Identifier.new('input', :type => %w[radio])]
|
36
|
-
|
52
|
+
|
53
|
+
#
|
37
54
|
# @api private
|
55
|
+
#
|
56
|
+
|
38
57
|
def initialize(container, *args)
|
39
58
|
super(container, %w[radio], *args)
|
40
59
|
end
|
41
60
|
|
61
|
+
#
|
42
62
|
# Set the radio button to the given value.
|
43
63
|
#
|
44
|
-
# radio.set?
|
64
|
+
# radio.set? #=> false
|
45
65
|
# radio.set
|
46
|
-
# radio.set?
|
66
|
+
# radio.set? #=> true
|
47
67
|
# radio.set(false)
|
48
|
-
# radio.set?
|
68
|
+
# radio.set? #=> false
|
69
|
+
#
|
70
|
+
|
49
71
|
def set(value = true)
|
50
72
|
assert_exists
|
51
73
|
assert_enabled
|
@@ -53,24 +75,32 @@ module Celerity
|
|
53
75
|
end
|
54
76
|
|
55
77
|
end
|
56
|
-
|
57
|
-
# This class is the celerity representation of a check box.
|
78
|
+
|
58
79
|
#
|
80
|
+
# This class is the representation of a check box.
|
81
|
+
#
|
82
|
+
|
59
83
|
class CheckBox < RadioCheckCommon
|
60
84
|
TAGS = [Identifier.new('input', :type => %w[checkbox])]
|
61
85
|
|
86
|
+
#
|
62
87
|
# @api private
|
88
|
+
#
|
89
|
+
|
63
90
|
def initialize(container, *args)
|
64
91
|
super(container, %w[checkbox], *args)
|
65
92
|
end
|
66
93
|
|
94
|
+
#
|
67
95
|
# Set the checkbox to the given value.
|
68
96
|
#
|
69
|
-
# checkbox.set?
|
97
|
+
# checkbox.set? #=> false
|
70
98
|
# checkbox.set
|
71
|
-
# checkbox.set?
|
99
|
+
# checkbox.set? #=> true
|
72
100
|
# checkbox.set(false)
|
73
|
-
# checkbox.set?
|
101
|
+
# checkbox.set? #=> false
|
102
|
+
#
|
103
|
+
|
74
104
|
def set(value = true)
|
75
105
|
assert_exists
|
76
106
|
assert_enabled
|