celerity_thingista 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +9 -0
- data/.gitmodules +3 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/LICENSE +278 -0
- data/README.rdoc +84 -0
- data/Rakefile +15 -0
- data/benchmark/bm_2000_spans.rb +48 -0
- data/benchmark/bm_digg.rb +26 -0
- data/benchmark/bm_google_images.rb +36 -0
- data/benchmark/bm_input_locator.rb +69 -0
- data/benchmark/bm_text_input.rb +19 -0
- data/benchmark/loader.rb +14 -0
- data/celerity.gemspec +26 -0
- data/lib/celerity.rb +75 -0
- data/lib/celerity/browser.rb +924 -0
- data/lib/celerity/clickable_element.rb +73 -0
- data/lib/celerity/collections.rb +164 -0
- data/lib/celerity/container.rb +802 -0
- data/lib/celerity/default_viewer.rb +14 -0
- data/lib/celerity/disabled_element.rb +40 -0
- data/lib/celerity/element.rb +314 -0
- data/lib/celerity/element_collection.rb +115 -0
- data/lib/celerity/element_locator.rb +164 -0
- data/lib/celerity/elements/button.rb +54 -0
- data/lib/celerity/elements/file_field.rb +29 -0
- data/lib/celerity/elements/form.rb +22 -0
- data/lib/celerity/elements/frame.rb +86 -0
- data/lib/celerity/elements/image.rb +89 -0
- data/lib/celerity/elements/label.rb +16 -0
- data/lib/celerity/elements/link.rb +43 -0
- data/lib/celerity/elements/meta.rb +14 -0
- data/lib/celerity/elements/non_control_elements.rb +124 -0
- data/lib/celerity/elements/option.rb +38 -0
- data/lib/celerity/elements/radio_check.rb +114 -0
- data/lib/celerity/elements/select_list.rb +146 -0
- data/lib/celerity/elements/table.rb +154 -0
- data/lib/celerity/elements/table_cell.rb +36 -0
- data/lib/celerity/elements/table_elements.rb +42 -0
- data/lib/celerity/elements/table_row.rb +54 -0
- data/lib/celerity/elements/text_field.rb +168 -0
- data/lib/celerity/exception.rb +83 -0
- data/lib/celerity/htmlunit.rb +64 -0
- data/lib/celerity/htmlunit/commons-codec-1.7.jar +0 -0
- data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/lib/celerity/htmlunit/commons-io-2.4.jar +0 -0
- data/lib/celerity/htmlunit/commons-lang3-3.1.jar +0 -0
- data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
- data/lib/celerity/htmlunit/cssparser-0.9.9.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.12.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.12.jar +0 -0
- data/lib/celerity/htmlunit/httpclient-4.2.3.jar +0 -0
- data/lib/celerity/htmlunit/httpcore-4.2.2.jar +0 -0
- data/lib/celerity/htmlunit/httpmime-4.2.3.jar +0 -0
- data/lib/celerity/htmlunit/jetty-http-8.1.9.v20130131.jar +0 -0
- data/lib/celerity/htmlunit/jetty-io-8.1.9.v20130131.jar +0 -0
- data/lib/celerity/htmlunit/jetty-util-8.1.9.v20130131.jar +0 -0
- data/lib/celerity/htmlunit/jetty-websocket-8.1.9.v20130131.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.18.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.10.0.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.4.01.jar +0 -0
- data/lib/celerity/identifier.rb +28 -0
- data/lib/celerity/ignoring_web_connection.rb +15 -0
- data/lib/celerity/input_element.rb +25 -0
- data/lib/celerity/javascript_debugger.rb +32 -0
- data/lib/celerity/listener.rb +143 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/short_inspect.rb +29 -0
- data/lib/celerity/util.rb +129 -0
- data/lib/celerity/version.rb +3 -0
- data/lib/celerity/viewer_connection.rb +89 -0
- data/lib/celerity/watir_compatibility.rb +70 -0
- data/lib/celerity/xpath_support.rb +50 -0
- data/spec/browser_authentication_spec.rb +16 -0
- data/spec/browser_spec.rb +439 -0
- data/spec/button_spec.rb +24 -0
- data/spec/clickable_element_spec.rb +39 -0
- data/spec/default_viewer_spec.rb +23 -0
- data/spec/element_spec.rb +77 -0
- data/spec/filefield_spec.rb +18 -0
- data/spec/htmlunit_spec.rb +63 -0
- data/spec/implementation.rb +7 -0
- data/spec/index_offset_spec.rb +24 -0
- data/spec/link_spec.rb +16 -0
- data/spec/listener_spec.rb +142 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/table_spec.rb +41 -0
- data/spec/watir_compatibility_spec.rb +32 -0
- data/tasks/benchmark.rake +4 -0
- data/tasks/check.rake +24 -0
- data/tasks/clean.rake +3 -0
- data/tasks/fix.rake +25 -0
- data/tasks/jar.rake +55 -0
- data/tasks/rdoc.rake +4 -0
- data/tasks/snapshot.rake +25 -0
- data/tasks/spec.rake +27 -0
- data/tasks/website.rake +10 -0
- data/tasks/yard.rake +16 -0
- data/website/benchmarks.html +237 -0
- data/website/css/color.css +153 -0
- data/website/css/hacks.css +3 -0
- data/website/css/layout.css +179 -0
- data/website/css/screen.css +5 -0
- data/website/css/textmate.css +226 -0
- data/website/css/typography.css +72 -0
- data/website/gfx/body_bg.gif +0 -0
- data/website/gfx/button_bg.jpg +0 -0
- data/website/gfx/header_bg.jpg +0 -0
- data/website/gfx/header_left.jpg +0 -0
- data/website/gfx/header_right.jpg +0 -0
- data/website/gfx/nav_bg.jpg +0 -0
- data/website/index.html +125 -0
- data/website/yard/index.html +1 -0
- metadata +246 -0
@@ -0,0 +1,154 @@
|
|
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 | [
|
10
|
+
:align,
|
11
|
+
:bgcolor,
|
12
|
+
:border,
|
13
|
+
:cellpadding,
|
14
|
+
:cellspacing,
|
15
|
+
:frame,
|
16
|
+
:rules,
|
17
|
+
:summary,
|
18
|
+
:width,
|
19
|
+
]
|
20
|
+
DEFAULT_HOW = :id
|
21
|
+
|
22
|
+
def locate
|
23
|
+
super
|
24
|
+
if @object
|
25
|
+
@rows = @object.getRows
|
26
|
+
@cells = []
|
27
|
+
@rows.each do |row|
|
28
|
+
row.getCells.each do |c|
|
29
|
+
@cells << c
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@object
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# @return [Celerity::TableRows]
|
39
|
+
#
|
40
|
+
|
41
|
+
def rows
|
42
|
+
assert_exists
|
43
|
+
TableRows.new(self, :object, @rows)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# @return [Celerity::TableCells]
|
48
|
+
#
|
49
|
+
|
50
|
+
def cells
|
51
|
+
assert_exists
|
52
|
+
TableCells.new(self, :object, @cells)
|
53
|
+
end
|
54
|
+
alias_method :tds, :cells
|
55
|
+
|
56
|
+
#
|
57
|
+
# Iterates through each row in the table.
|
58
|
+
# @yieldparam [Celerity::TableRow] row A row.
|
59
|
+
#
|
60
|
+
|
61
|
+
def each
|
62
|
+
assert_exists
|
63
|
+
@rows.each { |row| yield TableRow.new(self, :object, row) }
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Returns the TableRow at the given index (1-indexed).
|
68
|
+
#
|
69
|
+
# browser.table(:foo, 'bar')[1] # => #<TableRow...>
|
70
|
+
# browser.table(:foo, 'bar').child_row[1] # => #<TableRow...>
|
71
|
+
#
|
72
|
+
# @param [Fixnum] index The index of the wanted row, 1-indexed.
|
73
|
+
# @raise [Celerity::Exception::UnknownRowException]
|
74
|
+
# @return [Celerity::TableRow]
|
75
|
+
#
|
76
|
+
|
77
|
+
def child_row(index)
|
78
|
+
assert_exists
|
79
|
+
|
80
|
+
if (index - Celerity.index_offset) >= @rows.length
|
81
|
+
raise UnknownRowException, "Unable to locate a row at index #{index}"
|
82
|
+
end
|
83
|
+
|
84
|
+
TableRow.new(self, :object, @rows[index - Celerity.index_offset])
|
85
|
+
end
|
86
|
+
alias_method :[], :child_row
|
87
|
+
|
88
|
+
#
|
89
|
+
# Returns the TableCell at the given index (1-indexed).
|
90
|
+
#
|
91
|
+
# In a 10-column row, table.child_cell[11] will return the first cell on the second row.
|
92
|
+
#
|
93
|
+
# @param [Fixnum] index The index of the wanted cell, 1-indexed.
|
94
|
+
# @raise [Celerity::Exception::UnknownCellException]
|
95
|
+
# @return [Celerity::TableCell]
|
96
|
+
#
|
97
|
+
|
98
|
+
def child_cell(index)
|
99
|
+
assert_exists
|
100
|
+
|
101
|
+
if (index - Celerity.index_offset) >= @cells.length
|
102
|
+
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
103
|
+
end
|
104
|
+
|
105
|
+
TableCell.new(self, :object, @cells[index - Celerity.index_offset])
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# The number of rows in the table
|
110
|
+
# @return [Fixnum]
|
111
|
+
#
|
112
|
+
|
113
|
+
def row_count
|
114
|
+
assert_exists
|
115
|
+
@object.getRowCount
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Returns the number of columns on the row at the given index. (1-indexed)
|
120
|
+
# Default is the number of columns on the first row
|
121
|
+
# @param [Fixnum] index An index, 1-indexed (optional).
|
122
|
+
# @return [Fixnum]
|
123
|
+
#
|
124
|
+
|
125
|
+
def column_count(index = Celerity.index_offset)
|
126
|
+
assert_exists
|
127
|
+
@object.getRow(index - Celerity.index_offset).getCells.length
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Returns the text of each cell in the the table as a two-dimensional array.
|
132
|
+
# @return [Array<Array<String>>]
|
133
|
+
#
|
134
|
+
|
135
|
+
def to_a
|
136
|
+
assert_exists
|
137
|
+
# @object.getRows.map do |table_row|
|
138
|
+
# table_row.getCells.map { |td| td.asText.strip }
|
139
|
+
# end
|
140
|
+
rows.map do |table_row|
|
141
|
+
table_row.map { |td| td.text }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def column_values(column_number)
|
146
|
+
(0..row_count-1).map { |index| self[index + Celerity.index_offset][column_number].text }
|
147
|
+
end
|
148
|
+
|
149
|
+
def row_values(row_number)
|
150
|
+
(0..column_count(row_number)-1).map { |index| self[row_number][index + Celerity.index_offset].text }
|
151
|
+
end
|
152
|
+
|
153
|
+
end # Table
|
154
|
+
end # Celerity
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
class TableCell < Element
|
4
|
+
include Celerity::Exception
|
5
|
+
include ClickableElement
|
6
|
+
include Container
|
7
|
+
|
8
|
+
TAGS = [ Identifier.new('td') ]
|
9
|
+
ATTRIBUTES = BASE_ATTRIBUTES | CELLHALIGN_ATTRIBUTES | CELLVALIGN_ATTRIBUTES |
|
10
|
+
[
|
11
|
+
:abbr,
|
12
|
+
:axis,
|
13
|
+
:colspan,
|
14
|
+
:headers,
|
15
|
+
:rowspan,
|
16
|
+
:scope,
|
17
|
+
]
|
18
|
+
|
19
|
+
DEFAULT_HOW = :id
|
20
|
+
|
21
|
+
alias_method :to_s, :text # why?
|
22
|
+
|
23
|
+
def colspan
|
24
|
+
assert_exists
|
25
|
+
attribute_value = @object.getAttribute('colspan').to_i
|
26
|
+
attribute_value > 0 ? attribute_value : 1
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
#-- needs code review regarding attributes/correctness of this
|
32
|
+
class Th < TableCell
|
33
|
+
TAGS = [ Identifier.new('th')]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Celerity
|
2
|
+
class TableElement < Element
|
3
|
+
include Enumerable
|
4
|
+
include ClickableElement
|
5
|
+
|
6
|
+
ATTRIBUTES = BASE_ATTRIBUTES | CELLHALIGN_ATTRIBUTES | CELLVALIGN_ATTRIBUTES
|
7
|
+
DEFAULT_HOW = :id
|
8
|
+
|
9
|
+
def locate
|
10
|
+
super
|
11
|
+
@rows = @object.getRows if @object
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](index)
|
15
|
+
assert_exists
|
16
|
+
TableRow.new(self, :object, @rows[index - Celerity.index_offset])
|
17
|
+
end
|
18
|
+
|
19
|
+
def length
|
20
|
+
assert_exists
|
21
|
+
@object.getRows.length
|
22
|
+
end
|
23
|
+
|
24
|
+
def each
|
25
|
+
assert_exists
|
26
|
+
@rows.each { |row| yield TableRow.new(self, :object, row) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class TableBody < TableElement
|
31
|
+
TAGS = [ Identifier.new('tbody') ]
|
32
|
+
end
|
33
|
+
|
34
|
+
class TableFooter < TableElement
|
35
|
+
TAGS = [ Identifier.new('tfoot') ]
|
36
|
+
end
|
37
|
+
|
38
|
+
class TableHeader < TableElement
|
39
|
+
TAGS = [ Identifier.new('thead') ]
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Celerity
|
2
|
+
class TableRow < Element
|
3
|
+
include Enumerable
|
4
|
+
include ClickableElement
|
5
|
+
|
6
|
+
TAGS = [ Identifier.new('tr') ]
|
7
|
+
DEFAULT_HOW = :id
|
8
|
+
|
9
|
+
def locate
|
10
|
+
super
|
11
|
+
@cells = @object.getCells if @object
|
12
|
+
@object
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Yields each TableCell in this row to the given block.
|
17
|
+
#
|
18
|
+
|
19
|
+
def each
|
20
|
+
assert_exists
|
21
|
+
@cells.each { |cell| yield TableCell.new(self, :object, cell) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def cells
|
25
|
+
to_a
|
26
|
+
end
|
27
|
+
alias_method :tds, :cells
|
28
|
+
|
29
|
+
#
|
30
|
+
# Get the child cell at the given index
|
31
|
+
#
|
32
|
+
|
33
|
+
def child_cell(index)
|
34
|
+
assert_exists
|
35
|
+
|
36
|
+
if (index - Celerity.index_offset) >= @cells.length
|
37
|
+
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
38
|
+
end
|
39
|
+
|
40
|
+
TableCell.new(self, :object, @cells[index - Celerity.index_offset])
|
41
|
+
end
|
42
|
+
alias_method :[], :child_cell
|
43
|
+
|
44
|
+
#
|
45
|
+
# Number of cells in this row.
|
46
|
+
#
|
47
|
+
|
48
|
+
def column_count
|
49
|
+
assert_exists
|
50
|
+
@cells.length
|
51
|
+
end
|
52
|
+
|
53
|
+
end # TableRow
|
54
|
+
end # Celerity
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# Class representing text field elements
|
5
|
+
#
|
6
|
+
# This class is the main class for Text Fields
|
7
|
+
# Normally a user would not need to create this object as it is returned by the Watir::Container#text_field method
|
8
|
+
#
|
9
|
+
|
10
|
+
class TextField < InputElement
|
11
|
+
NON_TEXT_TYPES = %w[file radio checkbox submit reset image button hidden]
|
12
|
+
TAGS = [ Identifier.new('textarea'),
|
13
|
+
Identifier.new('input', :type => ["text", "password", /^(?!(#{ Regexp.union(*NON_TEXT_TYPES) })$)/]) ]
|
14
|
+
DEFAULT_HOW = :name
|
15
|
+
|
16
|
+
def visible?
|
17
|
+
assert_exists
|
18
|
+
type == 'hidden' ? false : super
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Clear the text field.
|
23
|
+
#
|
24
|
+
|
25
|
+
def clear
|
26
|
+
assert_exists
|
27
|
+
insert_string ''
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Set the text field to the given value.
|
32
|
+
# This ensures execution of JavaScript events (onkeypress etc.), but is slower than +value=+
|
33
|
+
#
|
34
|
+
|
35
|
+
def set(value)
|
36
|
+
assert_enabled
|
37
|
+
assert_not_readonly
|
38
|
+
clear
|
39
|
+
type_string(value.to_s)
|
40
|
+
|
41
|
+
value
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# This directly sets the text field to the given value, skipping exectuion of JavaScript events.
|
46
|
+
# Use +set+ if you want to run events on text fields.
|
47
|
+
#
|
48
|
+
|
49
|
+
def value=(value)
|
50
|
+
assert_enabled
|
51
|
+
assert_not_readonly
|
52
|
+
clear
|
53
|
+
|
54
|
+
insert_string value.to_s
|
55
|
+
|
56
|
+
value
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Returns the text in the text field.
|
61
|
+
#
|
62
|
+
|
63
|
+
def value
|
64
|
+
assert_exists
|
65
|
+
case @object.getTagName
|
66
|
+
when 'textarea'
|
67
|
+
@object.getText
|
68
|
+
when 'input'
|
69
|
+
@object.getValueAttribute
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Append the given value to the text in the text field.
|
75
|
+
#
|
76
|
+
|
77
|
+
def append(value)
|
78
|
+
assert_enabled
|
79
|
+
assert_not_readonly
|
80
|
+
type_string value
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def type
|
85
|
+
assert_exists
|
86
|
+
type = @object.getAttribute 'type'
|
87
|
+
|
88
|
+
NON_TEXT_TYPES.include?(type) ? type : 'text'
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# This bascially just moves the text to the other text field using TextField#append
|
93
|
+
# TODO: check if HtmlUnit supports some kind of dragging.
|
94
|
+
#
|
95
|
+
|
96
|
+
def drag_contents_to(how, what)
|
97
|
+
assert_exists # assert_enabled?
|
98
|
+
val = self.value
|
99
|
+
self.value = ''
|
100
|
+
@container.text_field(how, what).append(val)
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Check if the given text fields contains the given String or Regexp.
|
105
|
+
#
|
106
|
+
|
107
|
+
def contains_text(expected_text)
|
108
|
+
assert_exists
|
109
|
+
|
110
|
+
case expected_text
|
111
|
+
when Regexp
|
112
|
+
value() =~ expected_text
|
113
|
+
when String
|
114
|
+
value().index(expected_text)
|
115
|
+
else
|
116
|
+
raise TypeError, "expected String or Regexp, got #{expected_text.inspect}:#{expected_text.class}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# A boolean version of TextField#contains_text
|
122
|
+
#
|
123
|
+
# @param [String, Regexp] expected_text The text to look for.
|
124
|
+
# @return [boolean]
|
125
|
+
#
|
126
|
+
|
127
|
+
def verify_contains(expected)
|
128
|
+
# assert_exists called by contains_text
|
129
|
+
!!contains_text(expected)
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def type_string(value)
|
135
|
+
java.lang.String.new(value.to_java_bytes, @browser.page.getPageEncoding).toCharArray.each do |char|
|
136
|
+
@object.type(char)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def insert_string(value)
|
141
|
+
case @object.getTagName
|
142
|
+
when 'textarea'
|
143
|
+
@object.setText(value)
|
144
|
+
when 'input'
|
145
|
+
@object.setValueAttribute(value)
|
146
|
+
else
|
147
|
+
raise "unknown tag name #{@object.getTagName.inspect} for #{self.class}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end # TextField
|
152
|
+
|
153
|
+
#
|
154
|
+
# This class can be used to access hidden field objects
|
155
|
+
# Normally a user would not need to create this object as it is returned by the Celerity::Container#hidden method
|
156
|
+
#
|
157
|
+
|
158
|
+
class Hidden < TextField
|
159
|
+
TAGS = [ Identifier.new('input', :type => %w[hidden]) ]
|
160
|
+
DEFAULT_HOW = :name
|
161
|
+
|
162
|
+
def visible?
|
163
|
+
assert_exists
|
164
|
+
false
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end # Celerity
|