walidhalabi-celerity 0.0.6.11
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 +75 -0
- data/License.txt +621 -0
- data/README.txt +73 -0
- data/Rakefile +12 -0
- data/lib/celerity.rb +74 -0
- data/lib/celerity/browser.rb +811 -0
- data/lib/celerity/clickable_element.rb +69 -0
- data/lib/celerity/collections.rb +156 -0
- data/lib/celerity/container.rb +788 -0
- data/lib/celerity/default_viewer.rb +10 -0
- data/lib/celerity/disabled_element.rb +40 -0
- data/lib/celerity/element.rb +313 -0
- data/lib/celerity/element_collection.rb +107 -0
- data/lib/celerity/element_locator.rb +170 -0
- data/lib/celerity/elements/button.rb +43 -0
- data/lib/celerity/elements/file_field.rb +25 -0
- data/lib/celerity/elements/form.rb +23 -0
- data/lib/celerity/elements/frame.rb +75 -0
- data/lib/celerity/elements/image.rb +76 -0
- data/lib/celerity/elements/label.rb +11 -0
- data/lib/celerity/elements/link.rb +30 -0
- data/lib/celerity/elements/meta.rb +6 -0
- data/lib/celerity/elements/non_control_elements.rb +106 -0
- data/lib/celerity/elements/option.rb +32 -0
- data/lib/celerity/elements/radio_check.rb +115 -0
- data/lib/celerity/elements/select_list.rb +121 -0
- data/lib/celerity/elements/table.rb +144 -0
- data/lib/celerity/elements/table_cell.rb +29 -0
- data/lib/celerity/elements/table_elements.rb +42 -0
- data/lib/celerity/elements/table_row.rb +48 -0
- data/lib/celerity/elements/text_field.rb +169 -0
- data/lib/celerity/exception.rb +77 -0
- data/lib/celerity/htmlunit.rb +61 -0
- data/lib/celerity/htmlunit/commons-codec-1.3.jar +0 -0
- data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
- data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
- data/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
- data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
- data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.6-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.5.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.13-20090507.082850-2.jar +0 -0
- data/lib/celerity/htmlunit/sac-1.3.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/xercesImpl-2.8.1.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
- data/lib/celerity/identifier.rb +11 -0
- data/lib/celerity/input_element.rb +25 -0
- data/lib/celerity/listener.rb +141 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/short_inspect.rb +20 -0
- data/lib/celerity/util.rb +91 -0
- data/lib/celerity/version.rb +10 -0
- data/lib/celerity/watir_compatibility.rb +84 -0
- data/tasks/jar.rake +57 -0
- data/tasks/rdoc.rake +4 -0
- metadata +130 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# Superclass for for Span, Pre, Div, H1, ...
|
5
|
+
#
|
6
|
+
|
7
|
+
class NonControlElement < Element
|
8
|
+
include Exception
|
9
|
+
include ClickableElement
|
10
|
+
|
11
|
+
ATTRIBUTES = BASE_ATTRIBUTES
|
12
|
+
DEFAULT_HOW = :id
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
#--
|
17
|
+
# classes ordered alphabetically
|
18
|
+
#++
|
19
|
+
#
|
20
|
+
|
21
|
+
class Area < NonControlElement
|
22
|
+
ATTRIBUTES = ATTRIBUTES | [:shape, :coords, :href, :nohref, :alt, :tabindex, :accesskey, :onfocus, :onblur]
|
23
|
+
TAGS = [ Identifier.new('area') ]
|
24
|
+
end
|
25
|
+
|
26
|
+
class Dd < NonControlElement
|
27
|
+
TAGS = [ Identifier.new('dd')]
|
28
|
+
end
|
29
|
+
|
30
|
+
class Div < NonControlElement
|
31
|
+
TAGS = [ Identifier.new('div')]
|
32
|
+
end
|
33
|
+
|
34
|
+
class Dl < NonControlElement
|
35
|
+
TAGS = [ Identifier.new('dl')]
|
36
|
+
end
|
37
|
+
|
38
|
+
class Dt < NonControlElement
|
39
|
+
TAGS = [ Identifier.new('dt')]
|
40
|
+
end
|
41
|
+
|
42
|
+
class Em < NonControlElement
|
43
|
+
TAGS = [ Identifier.new('em')]
|
44
|
+
end
|
45
|
+
|
46
|
+
class H1 < NonControlElement
|
47
|
+
TAGS = [ Identifier.new('h1') ]
|
48
|
+
end
|
49
|
+
|
50
|
+
class H2 < NonControlElement
|
51
|
+
TAGS = [ Identifier.new('h2') ]
|
52
|
+
end
|
53
|
+
|
54
|
+
class H3 < NonControlElement
|
55
|
+
TAGS = [ Identifier.new('h3') ]
|
56
|
+
end
|
57
|
+
|
58
|
+
class H4 < NonControlElement
|
59
|
+
TAGS = [ Identifier.new('h4') ]
|
60
|
+
end
|
61
|
+
|
62
|
+
class H5 < NonControlElement
|
63
|
+
TAGS = [ Identifier.new('h5') ]
|
64
|
+
end
|
65
|
+
|
66
|
+
class H6 < NonControlElement
|
67
|
+
TAGS = [ Identifier.new('h6') ]
|
68
|
+
end
|
69
|
+
|
70
|
+
class Li < NonControlElement
|
71
|
+
TAGS = [ Identifier.new('li') ]
|
72
|
+
end
|
73
|
+
|
74
|
+
class Map < NonControlElement
|
75
|
+
TAGS = [ Identifier.new('map') ]
|
76
|
+
end
|
77
|
+
|
78
|
+
class Ol < NonControlElement
|
79
|
+
TAGS = [ Identifier.new('ol') ]
|
80
|
+
end
|
81
|
+
|
82
|
+
class P < NonControlElement
|
83
|
+
TAGS = [ Identifier.new('p') ]
|
84
|
+
end
|
85
|
+
|
86
|
+
class Pre < NonControlElement
|
87
|
+
TAGS = [ Identifier.new('pre')]
|
88
|
+
end
|
89
|
+
|
90
|
+
class Span < NonControlElement
|
91
|
+
TAGS = [ Identifier.new('span') ]
|
92
|
+
end
|
93
|
+
|
94
|
+
class Strong < NonControlElement
|
95
|
+
TAGS = [ Identifier.new('strong') ]
|
96
|
+
end
|
97
|
+
|
98
|
+
# class Title < NonControlElement
|
99
|
+
# TAGS = [ Identifier.new('title') ]
|
100
|
+
# end
|
101
|
+
|
102
|
+
class Ul < NonControlElement
|
103
|
+
TAGS = [ Identifier.new('ul') ]
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# Represents an option in a select list.
|
5
|
+
#
|
6
|
+
|
7
|
+
class Option < Element
|
8
|
+
include ClickableElement
|
9
|
+
include DisabledElement
|
10
|
+
|
11
|
+
TAGS = [ Identifier.new('option')]
|
12
|
+
ATTRIBUTES = BASE_ATTRIBUTES | [:selected, :disabled, :label, :value]
|
13
|
+
DEFAULT_HOW = :text
|
14
|
+
|
15
|
+
alias_method :select, :click
|
16
|
+
|
17
|
+
#
|
18
|
+
# Is this option selected?
|
19
|
+
#
|
20
|
+
|
21
|
+
def selected?
|
22
|
+
assert_exists
|
23
|
+
@object.isSelected
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
# overrides Container#label
|
28
|
+
assert_exists
|
29
|
+
@object.getLabelAttribute
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# Common superclass for radios and check boxes.
|
5
|
+
#
|
6
|
+
|
7
|
+
class RadioCheckCommon < InputElement
|
8
|
+
DEFAULT_HOW = :name
|
9
|
+
|
10
|
+
#
|
11
|
+
# Can optionally take a value parameter as a third arg, so we override initialize
|
12
|
+
#
|
13
|
+
|
14
|
+
def initialize(container, type, *args)
|
15
|
+
@type = type
|
16
|
+
case args.size
|
17
|
+
when 2
|
18
|
+
super(container, args[0] => args[1])
|
19
|
+
when 3
|
20
|
+
super(container, args[0] => args[1], :value => args[2])
|
21
|
+
else
|
22
|
+
super(container, *args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# returns true if the element is checked
|
28
|
+
# @return [true, false]
|
29
|
+
#
|
30
|
+
|
31
|
+
def set?
|
32
|
+
assert_exists
|
33
|
+
@object.isChecked
|
34
|
+
end
|
35
|
+
alias_method :checked?, :set?
|
36
|
+
|
37
|
+
#
|
38
|
+
# Unset this element.
|
39
|
+
#
|
40
|
+
|
41
|
+
def clear
|
42
|
+
set(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# This class is the representation of a radio button.
|
48
|
+
#
|
49
|
+
|
50
|
+
class Radio < RadioCheckCommon
|
51
|
+
TAGS = [Identifier.new('input', :type => %w[radio])]
|
52
|
+
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
|
57
|
+
def initialize(container, *args)
|
58
|
+
super(container, %w[radio], *args)
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Set the radio button to the given value.
|
63
|
+
#
|
64
|
+
# radio.set? #=> false
|
65
|
+
# radio.set
|
66
|
+
# radio.set? #=> true
|
67
|
+
# radio.set(false)
|
68
|
+
# radio.set? #=> false
|
69
|
+
#
|
70
|
+
|
71
|
+
def set(value = true)
|
72
|
+
assert_exists
|
73
|
+
assert_enabled
|
74
|
+
@container.update_page(value ? @object.click : @object.setChecked(value))
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# This class is the representation of a check box.
|
81
|
+
#
|
82
|
+
|
83
|
+
class CheckBox < RadioCheckCommon
|
84
|
+
TAGS = [Identifier.new('input', :type => %w[checkbox])]
|
85
|
+
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
|
90
|
+
def initialize(container, *args)
|
91
|
+
super(container, %w[checkbox], *args)
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Set the checkbox to the given value.
|
96
|
+
#
|
97
|
+
# checkbox.set? #=> false
|
98
|
+
# checkbox.set
|
99
|
+
# checkbox.set? #=> true
|
100
|
+
# checkbox.set(false)
|
101
|
+
# checkbox.set? #=> false
|
102
|
+
#
|
103
|
+
|
104
|
+
def set(value = true)
|
105
|
+
assert_exists
|
106
|
+
assert_enabled
|
107
|
+
|
108
|
+
if (value && !set?) || (!value && set?)
|
109
|
+
Log.debug(@object.inspect)
|
110
|
+
@container.update_page(@object.click)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Celerity
|
2
|
+
class SelectList < InputElement
|
3
|
+
TAGS = [ Identifier.new('select') ]
|
4
|
+
DEFAULT_HOW = :name
|
5
|
+
|
6
|
+
#
|
7
|
+
# @return [Array<String>] An array of strings representing the text value of the select list's options.
|
8
|
+
#
|
9
|
+
|
10
|
+
def options
|
11
|
+
assert_exists
|
12
|
+
@object.getOptions.map do |e|
|
13
|
+
e.asText.empty? ? e.getLabelAttribute : e.asText
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# @return [Array<String>] An array of strings representing the text value of the currently selected options.
|
19
|
+
#
|
20
|
+
|
21
|
+
def selected_options
|
22
|
+
assert_exists
|
23
|
+
@object.getSelectedOptions.map { |e| e.asText.empty? ? e.getLabelAttribute : e.asText }
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Clear all selected options
|
28
|
+
#
|
29
|
+
|
30
|
+
def clear
|
31
|
+
# assert_exists called by SelectList#type here
|
32
|
+
# TODO: should update page for each option changed?
|
33
|
+
@object.getSelectedOptions.each { |e| e.setSelected(false) } unless type() == 'select-one'
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Select the option(s) matching the given value.
|
38
|
+
# If several options match the value given, all will be selected.
|
39
|
+
#
|
40
|
+
# @param [String, Regexp] value A value.
|
41
|
+
# @raise [Celerity::Exception::NoValueFoundException] if the value does not exist.
|
42
|
+
# @return [String, nil] The option selected. If multiple options match, returns the first match
|
43
|
+
#
|
44
|
+
#
|
45
|
+
|
46
|
+
def select(value)
|
47
|
+
assert_exists
|
48
|
+
raise NoValueFoundException, "unknown option with value #{value.inspect} for select_list #{@conditions.inspect}" unless include?(value)
|
49
|
+
|
50
|
+
selected = nil
|
51
|
+
matching = @object.getOptions.select do |option|
|
52
|
+
next unless matches_option?(option, value)
|
53
|
+
|
54
|
+
selected ||= option.asText
|
55
|
+
@container.update_page option.click
|
56
|
+
end
|
57
|
+
|
58
|
+
selected
|
59
|
+
end
|
60
|
+
alias_method :set, :select
|
61
|
+
|
62
|
+
#
|
63
|
+
# Returns true if the select list has one or more options matching the given value.
|
64
|
+
#
|
65
|
+
# @param [String, Regexp] value A value.
|
66
|
+
# @return [true, false]
|
67
|
+
#
|
68
|
+
|
69
|
+
def include?(value)
|
70
|
+
assert_exists
|
71
|
+
!!@object.getOptions.find { |e| matches_option?(e, value) }
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Returns true if any of the selected options match the given value.
|
76
|
+
#
|
77
|
+
# @param [String, Regexp] value A value.
|
78
|
+
# @raise [Celerity::Exception::UnknownObjectException] if the value does not exist.
|
79
|
+
# @return [true, false]
|
80
|
+
#
|
81
|
+
|
82
|
+
def selected?(value)
|
83
|
+
assert_exists
|
84
|
+
raise UnknownObjectException, "unknown option with value #{value.inspect} for select_list #{@conditions.inspect}" unless include?(value)
|
85
|
+
!!@object.getOptions.find { |e| matches_option?(e, value) && e.isSelected }
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Returns 'select-multiple' if the select list has the 'multiple' attribute,
|
90
|
+
# defined, otherwise 'select-one'.
|
91
|
+
#
|
92
|
+
# @return [String]
|
93
|
+
#
|
94
|
+
|
95
|
+
def type
|
96
|
+
assert_exists
|
97
|
+
'select-' + (@object.hasAttribute('multiple') ? 'multiple' : 'one')
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Returns the value of the first selected option in the select list.
|
102
|
+
# Returns nil if no option is selected.
|
103
|
+
#
|
104
|
+
# @return [String, nil]
|
105
|
+
#
|
106
|
+
|
107
|
+
def value
|
108
|
+
assert_exists
|
109
|
+
if (option = @object.getSelectedOptions.to_a.first)
|
110
|
+
option.getValueAttribute
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def matches_option?(option, value)
|
117
|
+
matches?(option.asText, value) || (option.hasAttribute("label") && matches?(option.getLabelAttribute, value))
|
118
|
+
end
|
119
|
+
|
120
|
+
end # SelectList
|
121
|
+
end # Celerity
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
class Table < Element
|
4
|
+
include ClickableElement
|
5
|
+
include Enumerable
|
6
|
+
include Container
|
7
|
+
|
8
|
+
TAGS = [ Identifier.new('table') ]
|
9
|
+
ATTRIBUTES = BASE_ATTRIBUTES | [:summary, :width, :border, :frame, :rules,
|
10
|
+
:cellspacing, :cellpadding, :align, :bgcolor]
|
11
|
+
DEFAULT_HOW = :id
|
12
|
+
|
13
|
+
def locate
|
14
|
+
super
|
15
|
+
if @object # cant call assert_exists here, as an exists? method call will fail
|
16
|
+
@rows = @object.getRows
|
17
|
+
@cells = []
|
18
|
+
@rows.each do |row|
|
19
|
+
row.getCells.each do |c|
|
20
|
+
@cells << c
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@object
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# @return [Celerity::TableRows]
|
30
|
+
#
|
31
|
+
|
32
|
+
def rows
|
33
|
+
assert_exists
|
34
|
+
TableRows.new(self, :object, @rows)
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# @return [Celerity::TableCells]
|
39
|
+
#
|
40
|
+
|
41
|
+
def cells
|
42
|
+
assert_exists
|
43
|
+
TableCells.new(self, :object, @cells)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Iterates through each row in the table.
|
48
|
+
# @yieldparam [Celerity::TableRow] row A row.
|
49
|
+
#
|
50
|
+
|
51
|
+
def each
|
52
|
+
assert_exists
|
53
|
+
@rows.each { |row| yield TableRow.new(self, :object, row) }
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Returns the TableRow at the given index (1-indexed).
|
58
|
+
#
|
59
|
+
# browser.table(:foo, 'bar')[1] # => #<TableRow...>
|
60
|
+
# browser.table(:foo, 'bar').child_row[1] # => #<TableRow...>
|
61
|
+
#
|
62
|
+
# @param [Fixnum] index The index of the wanted row, 1-indexed.
|
63
|
+
# @raise [Celerity::Exception::UnknownRowException]
|
64
|
+
# @return [Celerity::TableRow]
|
65
|
+
#
|
66
|
+
|
67
|
+
def child_row(index)
|
68
|
+
assert_exists
|
69
|
+
|
70
|
+
if (index - Celerity.index_offset) >= @rows.length
|
71
|
+
raise UnknownRowException, "Unable to locate a row at index #{index}"
|
72
|
+
end
|
73
|
+
|
74
|
+
TableRow.new(self, :object, @rows[index - Celerity.index_offset])
|
75
|
+
end
|
76
|
+
alias_method :[], :child_row
|
77
|
+
|
78
|
+
#
|
79
|
+
# Returns the TableCell at the given index (1-indexed).
|
80
|
+
#
|
81
|
+
# In a 10-column row, table.child_cell[11] will return the first cell on the second row.
|
82
|
+
#
|
83
|
+
# @param [Fixnum] index The index of the wanted cell, 1-indexed.
|
84
|
+
# @raise [Celerity::Exception::UnknownCellException]
|
85
|
+
# @return [Celerity::TableCell]
|
86
|
+
#
|
87
|
+
|
88
|
+
def child_cell(index)
|
89
|
+
assert_exists
|
90
|
+
|
91
|
+
if (index - Celerity.index_offset) >= @cells.length
|
92
|
+
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
93
|
+
end
|
94
|
+
|
95
|
+
TableCell.new(self, :object, @cells[index - Celerity.index_offset])
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# The number of rows in the table
|
100
|
+
# @return [Fixnum]
|
101
|
+
#
|
102
|
+
|
103
|
+
def row_count
|
104
|
+
assert_exists
|
105
|
+
@object.getRowCount
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Returns the number of columns on the row at the given index. (1-indexed)
|
110
|
+
# Default is the number of columns on the first row
|
111
|
+
# @param [Fixnum] index An index, 1-indexed (optional).
|
112
|
+
# @return [Fixnum]
|
113
|
+
#
|
114
|
+
|
115
|
+
def column_count(index = Celerity.index_offset)
|
116
|
+
assert_exists
|
117
|
+
@object.getRow(index - Celerity.index_offset).getCells.length
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Returns the text of each cell in the the table as a two-dimensional array.
|
122
|
+
# @return [Array<Array<String>>]
|
123
|
+
#
|
124
|
+
|
125
|
+
def to_a
|
126
|
+
assert_exists
|
127
|
+
# @object.getRows.map do |table_row|
|
128
|
+
# table_row.getCells.map { |td| td.asText.strip }
|
129
|
+
# end
|
130
|
+
rows.map do |table_row|
|
131
|
+
table_row.map { |td| td.text }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def column_values(column_number)
|
136
|
+
(1..row_count).map { |index| self[index][column_number].text }
|
137
|
+
end
|
138
|
+
|
139
|
+
def row_values(row_number)
|
140
|
+
(1..column_count(row_number)).map { |index| self[row_number][index].text }
|
141
|
+
end
|
142
|
+
|
143
|
+
end # Table
|
144
|
+
end # Celerity
|