jarib-celerity 0.0.5.5 → 0.0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|