jarib-celerity 0.0.5
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 +42 -0
- data/License.txt +621 -0
- data/README.txt +64 -0
- data/Rakefile +12 -0
- data/lib/celerity.rb +59 -0
- data/lib/celerity/browser.rb +410 -0
- data/lib/celerity/clickable_element.rb +26 -0
- data/lib/celerity/collections.rb +148 -0
- data/lib/celerity/container.rb +488 -0
- data/lib/celerity/default_viewer.rb +10 -0
- data/lib/celerity/disabled_element.rb +27 -0
- data/lib/celerity/element.rb +241 -0
- data/lib/celerity/element_collections.rb +68 -0
- data/lib/celerity/element_locator.rb +167 -0
- data/lib/celerity/elements/button.rb +34 -0
- data/lib/celerity/elements/file_field.rb +17 -0
- data/lib/celerity/elements/form.rb +16 -0
- data/lib/celerity/elements/frame.rb +53 -0
- data/lib/celerity/elements/image.rb +57 -0
- data/lib/celerity/elements/label.rb +9 -0
- data/lib/celerity/elements/link.rb +12 -0
- data/lib/celerity/elements/meta.rb +6 -0
- data/lib/celerity/elements/non_control_elements.rb +93 -0
- data/lib/celerity/elements/option.rb +18 -0
- data/lib/celerity/elements/radio_check.rb +85 -0
- data/lib/celerity/elements/select_list.rb +81 -0
- data/lib/celerity/elements/table.rb +117 -0
- data/lib/celerity/elements/table_cell.rb +28 -0
- data/lib/celerity/elements/table_elements.rb +41 -0
- data/lib/celerity/elements/table_row.rb +36 -0
- data/lib/celerity/elements/text_field.rb +127 -0
- data/lib/celerity/exception.rb +40 -0
- data/lib/celerity/extra/method_generator.rb +158 -0
- data/lib/celerity/htmlunit.rb +41 -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.4-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.4-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.10-20081209.100757-4.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 +106 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/util.rb +79 -0
- data/lib/celerity/version.rb +9 -0
- data/lib/celerity/watir_compatibility.rb +85 -0
- data/tasks/benchmark.rake +4 -0
- data/tasks/deployment.rake +43 -0
- data/tasks/environment.rake +7 -0
- data/tasks/fix.rake +25 -0
- data/tasks/jar.rake +57 -0
- data/tasks/rdoc.rake +4 -0
- data/tasks/rspec.rake +30 -0
- data/tasks/simple_ci.rake +94 -0
- data/tasks/snapshot.rake +26 -0
- data/tasks/specserver.rake +21 -0
- data/tasks/website.rake +17 -0
- data/tasks/yard.rake +5 -0
- metadata +129 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
class Table < Element
|
4
|
+
include Enumerable
|
5
|
+
include Container
|
6
|
+
|
7
|
+
TAGS = [ Identifier.new('table') ]
|
8
|
+
ATTRIBUTES = BASE_ATTRIBUTES | [:summary, :width, :border, :frame, :rules,
|
9
|
+
:cellspacing, :cellpadding, :align, :bgcolor]
|
10
|
+
DEFAULT_HOW = :id
|
11
|
+
|
12
|
+
def locate
|
13
|
+
super
|
14
|
+
if @object # cant call assert_exists here, as an exists? method call will fail
|
15
|
+
@rows = @object.getRows
|
16
|
+
@cells = []
|
17
|
+
@rows.each do |row|
|
18
|
+
row.getCells.each do |c|
|
19
|
+
@cells << c
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Celerity::TableRows]
|
26
|
+
def rows
|
27
|
+
assert_exists
|
28
|
+
TableRows.new(self, :object, @rows)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Celerity::TableCells]
|
32
|
+
def cells
|
33
|
+
assert_exists
|
34
|
+
TableCells.new(self, :object, @cells)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Iterates through each row in the table.
|
38
|
+
# @yieldparam [Celerity::TableRow] row A row.
|
39
|
+
def each
|
40
|
+
assert_exists
|
41
|
+
@rows.each { |row| yield TableRow.new(self, :object, row) }
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the TableRow at the given index (1-indexed).
|
45
|
+
#
|
46
|
+
# browser.table(:foo, 'bar')[1] # => #<TableRow...>
|
47
|
+
# browser.table(:foo, 'bar').child_row[1] # => #<TableRow...>
|
48
|
+
#
|
49
|
+
# @param [Fixnum] index The index of the wanted row, 1-indexed.
|
50
|
+
# @raise [Celerity::Exception::UnknownRowException]
|
51
|
+
# @return [Celerity::TableRow]
|
52
|
+
def child_row(index)
|
53
|
+
assert_exists
|
54
|
+
|
55
|
+
if (index - INDEX_OFFSET) >= @rows.length
|
56
|
+
raise UnknownRowException, "Unable to locate a row at index #{index}"
|
57
|
+
end
|
58
|
+
|
59
|
+
TableRow.new(self, :object, @rows[index - INDEX_OFFSET])
|
60
|
+
end
|
61
|
+
alias_method :[], :child_row
|
62
|
+
|
63
|
+
# Returns the TableCell at the given index (1-indexed).
|
64
|
+
#
|
65
|
+
# In a 10-column row, table.child_cell[11] will return the first cell on the second row.
|
66
|
+
#
|
67
|
+
# @param [Fixnum] index The index of the wanted cell, 1-indexed.
|
68
|
+
# @raise [Celerity::Exception::UnknownCellException]
|
69
|
+
# @return [Celerity::TableCell]
|
70
|
+
def child_cell(index)
|
71
|
+
assert_exists
|
72
|
+
|
73
|
+
if (index - INDEX_OFFSET) >= @cells.length
|
74
|
+
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
75
|
+
end
|
76
|
+
TableCell.new(self, :object, @cells[index - INDEX_OFFSET])
|
77
|
+
end
|
78
|
+
|
79
|
+
# The number of rows in the table
|
80
|
+
# @return [Fixnum]
|
81
|
+
def row_count
|
82
|
+
assert_exists
|
83
|
+
@object.getRowCount
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the number of columns on the row at the given index. (1-indexed)
|
87
|
+
# Default is the number of columns on the first row
|
88
|
+
# @param [Fixnum] index An index, 1-indexed (optional).
|
89
|
+
# @return [Fixnum]
|
90
|
+
def column_count(index = INDEX_OFFSET)
|
91
|
+
assert_exists
|
92
|
+
@object.getRow(index - INDEX_OFFSET).getCells.length
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns the text of each cell in the the table as a two-dimensional array.
|
96
|
+
# @return [Array<Array<String>>]
|
97
|
+
def to_a
|
98
|
+
assert_exists
|
99
|
+
# @object.getRows.map do |table_row|
|
100
|
+
# table_row.getCells.map { |td| td.asText.strip }
|
101
|
+
# end
|
102
|
+
rows.map do |table_row|
|
103
|
+
table_row.map { |td| td.text }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def column_values(column_number)
|
108
|
+
(1..row_count).map { |index| self[index][column_number].text }
|
109
|
+
end
|
110
|
+
|
111
|
+
def row_values(row_number)
|
112
|
+
(1..column_count(row_number)).map { |index| self[row_number][index].text }
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
class TableCell < Element
|
4
|
+
include Celerity::Exception
|
5
|
+
include Container
|
6
|
+
|
7
|
+
TAGS = [ Identifier.new('td') ]
|
8
|
+
ATTRIBUTES = BASE_ATTRIBUTES | CELLHALIGN_ATTRIBUTES |
|
9
|
+
CELLVALIGN_ATTRIBUTES | [:abbr, :axis, :headers, :scope, :rowspan, :colspan]
|
10
|
+
|
11
|
+
DEFAULT_HOW = :id
|
12
|
+
|
13
|
+
alias_method :to_s, :text # why?
|
14
|
+
|
15
|
+
def colspan
|
16
|
+
assert_exists
|
17
|
+
attribute_value = @object.getAttributeValue('colspan').to_i
|
18
|
+
attribute_value > 0 ? attribute_value : 1
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
# needs code review regarding attributes/correctness of this
|
24
|
+
class Th < TableCell
|
25
|
+
TAGS = [ Identifier.new('th')]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Celerity
|
2
|
+
class TableElement < Element
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
ATTRIBUTES = BASE_ATTRIBUTES | CELLHALIGN_ATTRIBUTES | CELLVALIGN_ATTRIBUTES
|
6
|
+
DEFAULT_HOW = :id
|
7
|
+
|
8
|
+
def locate
|
9
|
+
super
|
10
|
+
@rows = @object.getRows if @object
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](index)
|
14
|
+
assert_exists
|
15
|
+
TableRow.new(self, :object, @rows[index - INDEX_OFFSET])
|
16
|
+
end
|
17
|
+
|
18
|
+
def length
|
19
|
+
assert_exists
|
20
|
+
@object.getRows.length
|
21
|
+
end
|
22
|
+
|
23
|
+
def each
|
24
|
+
assert_exists
|
25
|
+
@rows.each { |row| yield TableRow.new(self, :object, row) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class TableBody < TableElement
|
30
|
+
TAGS = [ Identifier.new('tbody') ]
|
31
|
+
end
|
32
|
+
|
33
|
+
class TableFooter < TableElement
|
34
|
+
TAGS = [ Identifier.new('tfoot') ]
|
35
|
+
end
|
36
|
+
|
37
|
+
class TableHeader < TableElement
|
38
|
+
TAGS = [ Identifier.new('thead') ]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Celerity
|
2
|
+
class TableRow < Element
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
TAGS = [ Identifier.new('tr') ]
|
6
|
+
DEFAULT_HOW = :id
|
7
|
+
|
8
|
+
def locate
|
9
|
+
super
|
10
|
+
@cells = @object.getCells if @object
|
11
|
+
end
|
12
|
+
|
13
|
+
# Yields each TableCell in this row cell to the given block.
|
14
|
+
def each
|
15
|
+
assert_exists
|
16
|
+
@cells.each { |cell| yield TableCell.new(self, :object, cell) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def child_cell(index)
|
20
|
+
assert_exists
|
21
|
+
|
22
|
+
if (index - INDEX_OFFSET) >= @cells.length
|
23
|
+
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
24
|
+
end
|
25
|
+
|
26
|
+
TableCell.new(self, :object, @cells[index - INDEX_OFFSET])
|
27
|
+
end
|
28
|
+
alias_method :[], :child_cell
|
29
|
+
|
30
|
+
def column_count
|
31
|
+
assert_exists
|
32
|
+
@cells.length
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Celerity
|
2
|
+
#
|
3
|
+
# Class representing text field elements
|
4
|
+
#
|
5
|
+
# This class is the main class for Text Fields
|
6
|
+
# Normally a user would not need to create this object as it is returned by the Watir::Container#text_field method
|
7
|
+
class TextField < InputElement
|
8
|
+
NON_TEXT_TYPES = %w[file radio checkbox submit reset image button hidden]
|
9
|
+
TAGS = [ Identifier.new('textarea'),
|
10
|
+
Identifier.new('input', :type => ["text", "password", /^(?!(#{ Regexp.union(*NON_TEXT_TYPES) })$)/]) ]
|
11
|
+
DEFAULT_HOW = :name
|
12
|
+
|
13
|
+
# Clear the text field.
|
14
|
+
def clear
|
15
|
+
assert_exists
|
16
|
+
insert_string ''
|
17
|
+
end
|
18
|
+
|
19
|
+
# Set the text field to the given value.
|
20
|
+
# This ensures execution of JavaScript events (onkeypress etc.), but is slower than +value=+
|
21
|
+
def set(value)
|
22
|
+
assert_enabled
|
23
|
+
assert_not_readonly
|
24
|
+
clear
|
25
|
+
type_string(value.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
# This directly sets the text field to the given value, skipping exectuion of JavaScript events.
|
29
|
+
# Use +set+ if you want to run events on text fields.
|
30
|
+
def value=(value)
|
31
|
+
assert_enabled
|
32
|
+
assert_not_readonly
|
33
|
+
clear
|
34
|
+
|
35
|
+
insert_string value.to_s
|
36
|
+
|
37
|
+
value
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the text in the text field.
|
41
|
+
def value
|
42
|
+
assert_exists
|
43
|
+
case @object.getTagName
|
44
|
+
when 'textarea'
|
45
|
+
@object.getText
|
46
|
+
when 'input'
|
47
|
+
@object.getValueAttribute
|
48
|
+
end
|
49
|
+
end
|
50
|
+
alias_method :get_contents, :value
|
51
|
+
|
52
|
+
# Append the given value to the text in the text field.
|
53
|
+
def append(value)
|
54
|
+
assert_enabled
|
55
|
+
assert_not_readonly
|
56
|
+
type_string(value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def type
|
60
|
+
assert_exists
|
61
|
+
type = @object.getAttributeValue('type')
|
62
|
+
|
63
|
+
if NON_TEXT_TYPES.include?(type)
|
64
|
+
type
|
65
|
+
else
|
66
|
+
'text'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# This bascially just moves the text to the other text field using TextField#append
|
71
|
+
# Should check if the HtmlUnit API supports some kind of dragging.
|
72
|
+
def drag_contents_to(how, what)
|
73
|
+
assert_exists # assert_enabled?
|
74
|
+
val = self.value
|
75
|
+
self.value = ''
|
76
|
+
@container.text_field(how, what).append(val)
|
77
|
+
end
|
78
|
+
|
79
|
+
def contains_text(expected_text)
|
80
|
+
assert_exists
|
81
|
+
|
82
|
+
case expected_text
|
83
|
+
when Regexp
|
84
|
+
value() =~ expected_text
|
85
|
+
when String
|
86
|
+
value().index(expected_text)
|
87
|
+
else
|
88
|
+
raise TypeError, "expected String or Regexp, got #{expected_text.inspect}:#{expected_text.class}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# A boolean version of TextField#contains_text
|
93
|
+
# @param [String, Regexp] expected_text The text to look for.
|
94
|
+
# @return [boolean]
|
95
|
+
def verify_contains(expected)
|
96
|
+
# assert_exists called by contains_text
|
97
|
+
!!contains_text(expected)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def type_string(value)
|
103
|
+
java.lang.String.new(value.to_java_bytes, @container.page.getPageEncoding).toCharArray.each do |char|
|
104
|
+
@container.update_page @object.type(char)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def insert_string(value)
|
109
|
+
case @object.getTagName
|
110
|
+
when 'textarea'
|
111
|
+
@object.setText(value)
|
112
|
+
when 'input'
|
113
|
+
@object.setValueAttribute(value)
|
114
|
+
else
|
115
|
+
raise "unknown tag name #{@object.getTagName.inspect} for #{self.class}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# this class can be used to access hidden field objects
|
121
|
+
# Normally a user would not need to create this object as it is returned by the Celerity::Container#hidden method
|
122
|
+
class Hidden < TextField
|
123
|
+
TAGS = [ Identifier.new('input', :type => %w[hidden]) ]
|
124
|
+
DEFAULT_HOW = :name
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Celerity
|
2
|
+
module Exception
|
3
|
+
|
4
|
+
# Superclass for all Celerity exceptions.
|
5
|
+
class CelerityException < StandardError; end
|
6
|
+
|
7
|
+
# This exception is thrown if an attempt is made to access an object that doesn't exist
|
8
|
+
class UnknownObjectException < CelerityException; end
|
9
|
+
|
10
|
+
# This exception is thrown if an attempt is made to access an object that is in a disabled state
|
11
|
+
class ObjectDisabledException < CelerityException; end
|
12
|
+
|
13
|
+
# This exception is thrown if an attempt is made to access a frame that cannot be found
|
14
|
+
class UnknownFrameException < CelerityException; end
|
15
|
+
|
16
|
+
# This exception is thrown if an attempt is made to access a form that cannot be found
|
17
|
+
class UnknownFormException < CelerityException; end
|
18
|
+
|
19
|
+
# This exception is thrown if an attempt is made to access an object that is in a read-only state
|
20
|
+
class ObjectReadOnlyException < CelerityException; end
|
21
|
+
|
22
|
+
# This exception is thrown if an attempt is made to access an object when the specified value cannot be found
|
23
|
+
class NoValueFoundException < CelerityException; end
|
24
|
+
|
25
|
+
# This exception gets raised if the how argument is wrong.
|
26
|
+
class MissingWayOfFindingObjectException < CelerityException; end
|
27
|
+
|
28
|
+
# This exception is raised if an attempt is made to access a table row that doesn't exist
|
29
|
+
class UnknownRowException < CelerityException; end
|
30
|
+
|
31
|
+
# This exception is raised if an attempt is made to access a table cell that doesn't exist
|
32
|
+
class UnknownCellException < CelerityException; end
|
33
|
+
|
34
|
+
# This exception is thrown if an http error, such as a 404, 500 etc is encountered while navigating
|
35
|
+
class NavigationException < CelerityException; end
|
36
|
+
|
37
|
+
# This exception is thrown if an unexpected content type is returned by the server.
|
38
|
+
class UnexpectedPageException < CelerityException; end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "uri"
|
3
|
+
require "active_support"
|
4
|
+
|
5
|
+
#--
|
6
|
+
# http://api.rubyonrails.com/classes/Inflector.html#M001621
|
7
|
+
#++
|
8
|
+
class String # :nodoc:
|
9
|
+
def underscore
|
10
|
+
gsub(/::/, '/').
|
11
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
12
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
13
|
+
tr("-", "_").
|
14
|
+
downcase
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Celerity
|
19
|
+
# Experimental - generate a method definition for accessing elements on the current page.
|
20
|
+
class MethodGenerator
|
21
|
+
|
22
|
+
ELEMENTS = %w[text_field select_list radio checkbox button].map { |e| e.to_sym }
|
23
|
+
BUGGY_ELEMENTS = %w[radio checkbox].map { |e| e.to_sym }
|
24
|
+
|
25
|
+
def initialize(ie, opts = {})
|
26
|
+
@ie = ie
|
27
|
+
@opts = opts
|
28
|
+
@browser = @opts[:browser] || '@ie'
|
29
|
+
|
30
|
+
@docs = " # Fills in the page at #{@ie.url}\n #\n"
|
31
|
+
@docs << " # Parameters:\n #\n"
|
32
|
+
@doc_elements = []
|
33
|
+
|
34
|
+
@method = " def #{@opts[:method_name] || 'generated_method'}(opts = {})\n\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse
|
38
|
+
ELEMENTS.each do |elem|
|
39
|
+
@method << " # buggy!\n" if BUGGY_ELEMENTS.include?(elem)
|
40
|
+
add_elements(elem)
|
41
|
+
end
|
42
|
+
add_elements(:link) if @opts[:include_links]
|
43
|
+
@method << " end\n\n"
|
44
|
+
|
45
|
+
# fix docs
|
46
|
+
max = @doc_elements.map { |symbol, _| symbol.to_s.size }.max
|
47
|
+
@doc_elements.each do |sym, desc|
|
48
|
+
@docs << " # #{sym.to_s.ljust(max)} => #{desc}\n"
|
49
|
+
end
|
50
|
+
@docs << " #\n"*2
|
51
|
+
@docs + @method
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def add_elements(symbol)
|
57
|
+
symbol = symbol.to_sym
|
58
|
+
symbol_pluralized = symbol.to_s.pluralize.to_sym
|
59
|
+
@ie.send(symbol_pluralized).each_with_index do |elem, idx|
|
60
|
+
self.send("add_#{symbol}".to_sym, elem, idx)
|
61
|
+
end
|
62
|
+
|
63
|
+
@method << "\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_text_field(elem, idx)
|
67
|
+
how, what = find_identifier(elem) || [:index, (idx + 1).to_s]
|
68
|
+
@method << " #{@browser}.text_field(#{how.inspect}, #{what.inspect}).value = "
|
69
|
+
symbol = (how == :index) ? ":text_field_#{what.underscore}" : ":#{what.underscore}"
|
70
|
+
@method << "opts[#{symbol}]\n"
|
71
|
+
@doc_elements << [symbol, "value for text field #{what.inspect}"]
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_select_list(elem, idx)
|
75
|
+
how, what = find_identifier(elem) || [:index, (idx + 1).to_s]
|
76
|
+
@method << " #{@browser}.select_list(#{how.inspect}, #{what.inspect}).select("
|
77
|
+
symbol = (how == :index) ? ":select_list_#{what.underscore}" : ":#{what.underscore}"
|
78
|
+
@method << "opts[#{symbol}])\n"
|
79
|
+
@doc_elements << [symbol, "option to select for select list #{what.inspect}"]
|
80
|
+
end
|
81
|
+
|
82
|
+
def add_radio(elem, idx)
|
83
|
+
how, what = find_identifier(elem) || [:index, (idx + 1).to_s]
|
84
|
+
@method << " #{@browser}.radio(#{how.inspect}, #{what.inspect}, "
|
85
|
+
|
86
|
+
if (value = elem.value).empty?
|
87
|
+
symbol = (how == :index) ? ":radio_#{what.underscore}" : ":#{what.underscore}"
|
88
|
+
else
|
89
|
+
symbol = ":#{what.underscore}_#{value.underscore}"
|
90
|
+
@method << "#{value.inspect}).set if opts[#{symbol}]\n"
|
91
|
+
end
|
92
|
+
|
93
|
+
@doc_elements << [symbol, "set the radio with id/value #{what.inspect}"]
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_checkbox(elem, idx)
|
97
|
+
how, what = find_identifier(elem) || [:index, (idx + 1).to_s]
|
98
|
+
@method << " #{@browser}.checkbox(#{how.inspect}, #{what.inspect}, "
|
99
|
+
symbol = (how == :index) ? ":checkbox_#{what.underscore}" : ":#{what.underscore}"
|
100
|
+
@method << "#{elem.value.inspect}).set if opts[#{symbol}]\n"
|
101
|
+
|
102
|
+
@doc_elements << [symbol, "set the checkbox with id/value #{what.inspect}"]
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_button(elem, idx)
|
106
|
+
how, what = find_identifier(elem) || [:index, (idx + 1).to_s]
|
107
|
+
@method << " #{@browser}.button(#{how.inspect}, #{what.inspect}).click\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_link(elem, idx)
|
111
|
+
if (href = elem.href) =~ /javascript/
|
112
|
+
how, what = :index, (idx + 1).to_s
|
113
|
+
else
|
114
|
+
how = :url
|
115
|
+
|
116
|
+
begin
|
117
|
+
uri = URI.parse(href)
|
118
|
+
what = Regexp.new(Regexp.escape(uri.to_s.sub(/.*#{uri.host}\//, '')))
|
119
|
+
rescue URI::InvalidURIError
|
120
|
+
what = href
|
121
|
+
end
|
122
|
+
end
|
123
|
+
@method << " #{@browser}.link(#{how.inspect}, #{what.inspect}).click\n"
|
124
|
+
end
|
125
|
+
|
126
|
+
def find_identifier(element)
|
127
|
+
# could use ATTRIBUTES if they were 'weighted' somehow?
|
128
|
+
attrs = element.class::ATTRIBUTES
|
129
|
+
[:id, :name].each do |attribute|
|
130
|
+
return [attribute, element.send(attribute)] if attrs.include?(attribute) && !element.send(attribute).empty?
|
131
|
+
end
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
end # MethodGenerator
|
136
|
+
|
137
|
+
class Browser
|
138
|
+
# Experimental - generate a method definition for accessing elements on the current page
|
139
|
+
# Not loaded by default - need to require 'celerity/extra/method_generator'
|
140
|
+
def generate_method(opts = {})
|
141
|
+
MethodGenerator.new(self, opts).parse
|
142
|
+
end
|
143
|
+
end # Browser
|
144
|
+
|
145
|
+
end # Celerity
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
# if __FILE__ == $0
|
150
|
+
# require File.dirname(__FILE__) + "/../spec/spec_helper"
|
151
|
+
# $stdout.sync = true
|
152
|
+
# @ie = Browser.new
|
153
|
+
# @ie.goto(TEST_HOST + "/forms_with_input_elements.html")
|
154
|
+
#
|
155
|
+
# puts MethodGenerator.new(@ie).parse
|
156
|
+
# @ie.goto(TEST_HOST + "/forms3.html")
|
157
|
+
# puts MethodGenerator.new(@ie).parse
|
158
|
+
# end
|