oki-celerity 0.8.1.dev

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.
Files changed (77) hide show
  1. data/HISTORY +111 -0
  2. data/LICENSE +621 -0
  3. data/README.rdoc +80 -0
  4. data/Rakefile +11 -0
  5. data/VERSION.yml +5 -0
  6. data/celerity.gemspec +126 -0
  7. data/lib/celerity/browser.rb +908 -0
  8. data/lib/celerity/clickable_element.rb +73 -0
  9. data/lib/celerity/collections.rb +164 -0
  10. data/lib/celerity/container.rb +800 -0
  11. data/lib/celerity/default_viewer.rb +14 -0
  12. data/lib/celerity/disabled_element.rb +40 -0
  13. data/lib/celerity/element.rb +311 -0
  14. data/lib/celerity/element_collection.rb +107 -0
  15. data/lib/celerity/element_locator.rb +164 -0
  16. data/lib/celerity/elements/button.rb +54 -0
  17. data/lib/celerity/elements/file_field.rb +29 -0
  18. data/lib/celerity/elements/form.rb +22 -0
  19. data/lib/celerity/elements/frame.rb +86 -0
  20. data/lib/celerity/elements/image.rb +89 -0
  21. data/lib/celerity/elements/label.rb +16 -0
  22. data/lib/celerity/elements/link.rb +43 -0
  23. data/lib/celerity/elements/meta.rb +14 -0
  24. data/lib/celerity/elements/non_control_elements.rb +124 -0
  25. data/lib/celerity/elements/option.rb +38 -0
  26. data/lib/celerity/elements/radio_check.rb +114 -0
  27. data/lib/celerity/elements/select_list.rb +146 -0
  28. data/lib/celerity/elements/table.rb +153 -0
  29. data/lib/celerity/elements/table_cell.rb +36 -0
  30. data/lib/celerity/elements/table_elements.rb +42 -0
  31. data/lib/celerity/elements/table_row.rb +49 -0
  32. data/lib/celerity/elements/text_field.rb +168 -0
  33. data/lib/celerity/exception.rb +83 -0
  34. data/lib/celerity/htmlunit/apache-mime4j-0.6.jar +0 -0
  35. data/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
  36. data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  37. data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  38. data/lib/celerity/htmlunit/commons-lang-2.5.jar +0 -0
  39. data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  40. data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  41. data/lib/celerity/htmlunit/htmlunit-2.9-SNAPSHOT.jar +0 -0
  42. data/lib/celerity/htmlunit/htmlunit-core-js-2.8.jar +0 -0
  43. data/lib/celerity/htmlunit/httpclient-4.0.1.jar +0 -0
  44. data/lib/celerity/htmlunit/httpcore-4.0.1.jar +0 -0
  45. data/lib/celerity/htmlunit/httpmime-4.0.1.jar +0 -0
  46. data/lib/celerity/htmlunit/nekohtml-1.9.14.jar +0 -0
  47. data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  48. data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  49. data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  50. data/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
  51. data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  52. data/lib/celerity/htmlunit.rb +64 -0
  53. data/lib/celerity/identifier.rb +28 -0
  54. data/lib/celerity/ignoring_web_connection.rb +15 -0
  55. data/lib/celerity/input_element.rb +25 -0
  56. data/lib/celerity/javascript_debugger.rb +32 -0
  57. data/lib/celerity/listener.rb +143 -0
  58. data/lib/celerity/resources/no_viewer.png +0 -0
  59. data/lib/celerity/short_inspect.rb +20 -0
  60. data/lib/celerity/util.rb +129 -0
  61. data/lib/celerity/version.rb +3 -0
  62. data/lib/celerity/viewer_connection.rb +89 -0
  63. data/lib/celerity/watir_compatibility.rb +70 -0
  64. data/lib/celerity/xpath_support.rb +52 -0
  65. data/lib/celerity.rb +77 -0
  66. data/tasks/benchmark.rake +4 -0
  67. data/tasks/check.rake +24 -0
  68. data/tasks/clean.rake +3 -0
  69. data/tasks/fix.rake +25 -0
  70. data/tasks/jar.rake +55 -0
  71. data/tasks/jeweler.rake +28 -0
  72. data/tasks/rdoc.rake +4 -0
  73. data/tasks/snapshot.rake +25 -0
  74. data/tasks/spec.rake +26 -0
  75. data/tasks/website.rake +10 -0
  76. data/tasks/yard.rake +16 -0
  77. metadata +204 -0
@@ -0,0 +1,153 @@
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
+
55
+ #
56
+ # Iterates through each row in the table.
57
+ # @yieldparam [Celerity::TableRow] row A row.
58
+ #
59
+
60
+ def each
61
+ assert_exists
62
+ @rows.each { |row| yield TableRow.new(self, :object, row) }
63
+ end
64
+
65
+ #
66
+ # Returns the TableRow at the given index (1-indexed).
67
+ #
68
+ # browser.table(:foo, 'bar')[1] # => #<TableRow...>
69
+ # browser.table(:foo, 'bar').child_row[1] # => #<TableRow...>
70
+ #
71
+ # @param [Fixnum] index The index of the wanted row, 1-indexed.
72
+ # @raise [Celerity::Exception::UnknownRowException]
73
+ # @return [Celerity::TableRow]
74
+ #
75
+
76
+ def child_row(index)
77
+ assert_exists
78
+
79
+ if (index - Celerity.index_offset) >= @rows.length
80
+ raise UnknownRowException, "Unable to locate a row at index #{index}"
81
+ end
82
+
83
+ TableRow.new(self, :object, @rows[index - Celerity.index_offset])
84
+ end
85
+ alias_method :[], :child_row
86
+
87
+ #
88
+ # Returns the TableCell at the given index (1-indexed).
89
+ #
90
+ # In a 10-column row, table.child_cell[11] will return the first cell on the second row.
91
+ #
92
+ # @param [Fixnum] index The index of the wanted cell, 1-indexed.
93
+ # @raise [Celerity::Exception::UnknownCellException]
94
+ # @return [Celerity::TableCell]
95
+ #
96
+
97
+ def child_cell(index)
98
+ assert_exists
99
+
100
+ if (index - Celerity.index_offset) >= @cells.length
101
+ raise UnknownCellException, "Unable to locate a cell at index #{index}"
102
+ end
103
+
104
+ TableCell.new(self, :object, @cells[index - Celerity.index_offset])
105
+ end
106
+
107
+ #
108
+ # The number of rows in the table
109
+ # @return [Fixnum]
110
+ #
111
+
112
+ def row_count
113
+ assert_exists
114
+ @object.getRowCount
115
+ end
116
+
117
+ #
118
+ # Returns the number of columns on the row at the given index. (1-indexed)
119
+ # Default is the number of columns on the first row
120
+ # @param [Fixnum] index An index, 1-indexed (optional).
121
+ # @return [Fixnum]
122
+ #
123
+
124
+ def column_count(index = Celerity.index_offset)
125
+ assert_exists
126
+ @object.getRow(index - Celerity.index_offset).getCells.length
127
+ end
128
+
129
+ #
130
+ # Returns the text of each cell in the the table as a two-dimensional array.
131
+ # @return [Array<Array<String>>]
132
+ #
133
+
134
+ def to_a
135
+ assert_exists
136
+ # @object.getRows.map do |table_row|
137
+ # table_row.getCells.map { |td| td.asText.strip }
138
+ # end
139
+ rows.map do |table_row|
140
+ table_row.map { |td| td.text }
141
+ end
142
+ end
143
+
144
+ def column_values(column_number)
145
+ (0..row_count-1).map { |index| self[index + Celerity.index_offset][column_number].text }
146
+ end
147
+
148
+ def row_values(row_number)
149
+ (0..column_count(row_number)-1).map { |index| self[row_number][index + Celerity.index_offset].text }
150
+ end
151
+
152
+ end # Table
153
+ 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,49 @@
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
+ #
25
+ # Get the child cell at the given index
26
+ #
27
+
28
+ def child_cell(index)
29
+ assert_exists
30
+
31
+ if (index - Celerity.index_offset) >= @cells.length
32
+ raise UnknownCellException, "Unable to locate a cell at index #{index}"
33
+ end
34
+
35
+ TableCell.new(self, :object, @cells[index - Celerity.index_offset])
36
+ end
37
+ alias_method :[], :child_cell
38
+
39
+ #
40
+ # Number of cells in this row.
41
+ #
42
+
43
+ def column_count
44
+ assert_exists
45
+ @cells.length
46
+ end
47
+
48
+ end # TableRow
49
+ 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
@@ -0,0 +1,83 @@
1
+ module Celerity
2
+ module Exception
3
+
4
+ #
5
+ # Superclass for all Celerity exceptions.
6
+ #
7
+
8
+ class CelerityException < StandardError; end
9
+
10
+ #
11
+ # This exception is thrown if an attempt is made to access an object that doesn't exist
12
+ #
13
+
14
+ class UnknownObjectException < CelerityException; end
15
+
16
+ #
17
+ # This exception is thrown if an attempt is made to access an object that is in a disabled state
18
+ #
19
+
20
+ class ObjectDisabledException < CelerityException; end
21
+
22
+ #
23
+ # This exception is thrown if an attempt is made to access a frame that cannot be found
24
+ #
25
+
26
+ class UnknownFrameException < CelerityException; end
27
+
28
+ #
29
+ # This exception is thrown if an attempt is made to access a form that cannot be found
30
+ #
31
+
32
+ class UnknownFormException < CelerityException; end
33
+
34
+ #
35
+ # This exception is thrown if an attempt is made to access an object that is in a read-only state
36
+ #
37
+
38
+ class ObjectReadOnlyException < CelerityException; end
39
+
40
+ #
41
+ # This exception is thrown if an attempt is made to access an object when the specified value cannot be found
42
+ #
43
+
44
+ class NoValueFoundException < CelerityException; end
45
+
46
+ #
47
+ # This exception gets raised if the how argument is wrong.
48
+ #
49
+
50
+ class MissingWayOfFindingObjectException < CelerityException; end
51
+
52
+ #
53
+ # This exception is raised if an attempt is made to access a table row that doesn't exist
54
+ #
55
+
56
+ class UnknownRowException < CelerityException; end
57
+
58
+ #
59
+ # This exception is raised if an attempt is made to access a table cell that doesn't exist
60
+ #
61
+
62
+ class UnknownCellException < CelerityException; end
63
+
64
+ #
65
+ # This exception is thrown if an http error, such as a 404, 500 etc is encountered while navigating
66
+ #
67
+
68
+ class NavigationException < CelerityException; end
69
+
70
+ #
71
+ # This exception is thrown if an unexpected content type is returned by the server.
72
+ #
73
+
74
+ class UnexpectedPageException < CelerityException; end
75
+
76
+ #
77
+ # This exception is thrown if an unexpected content type is returned by the server.
78
+ #
79
+
80
+ class CookieNotFoundError < CelerityException; end
81
+
82
+ end # Exception
83
+ end # Celerity
Binary file
@@ -0,0 +1,64 @@
1
+ module Celerity
2
+ Jars = Dir[File.dirname(__FILE__) + '/htmlunit/*.jar']
3
+ Jars.each { |jar| require(jar) }
4
+
5
+ module JsxHelper
6
+ def method_missing(meth, *args, &blk)
7
+ m = ["jsxGet_#{meth}", "jsx_get_#{meth}"].find { |m| respond_to?(m) }
8
+ m ? __send__(m) : super
9
+ end
10
+ end
11
+ end
12
+
13
+ module HtmlUnit
14
+ include_package 'com.gargoylesoftware.htmlunit'
15
+
16
+ module Html
17
+ include_package 'com.gargoylesoftware.htmlunit.html'
18
+ end
19
+
20
+ module Util
21
+ include_package 'com.gargoylesoftware.htmlunit.util'
22
+ end
23
+
24
+ end
25
+
26
+ module Java::OrgW3cDom::NamedNodeMap
27
+ include Enumerable
28
+
29
+ def each
30
+ 0.upto(getLength - 1) do |idx|
31
+ yield item(idx)
32
+ end
33
+ end
34
+ end
35
+
36
+ module Java::JavaLang::Iterable
37
+ include Enumerable
38
+
39
+ def each
40
+ it = iterator
41
+ yield it.next while it.hasNext
42
+ end
43
+
44
+ end unless Java::JavaLang::Iterable < Enumerable # depends on JRuby version
45
+
46
+ class Java::ComGargoylesoftwareHtmlunitHtml::HtmlPage
47
+ def inspect
48
+ '#<HtmlPage:0x%s(%s)>' % [self.hash.to_s(16), getWebResponse.getWebRequest.getUrl.toString]
49
+ end
50
+ end
51
+
52
+ class Java::ComGargoylesoftwareHtmlunitHtml::HtmlElement
53
+ def inspect
54
+ '#<%s:0x%s>' % [self.class.name.split("::").last, self.hash.to_s(16)]
55
+ end
56
+ end
57
+
58
+ class Java::ComGargoylesoftwareHtmlunitJavascriptHostHtml::HTMLElement
59
+ include Celerity::JsxHelper
60
+ end
61
+
62
+ class Java::ComGargoylesoftwareHtmlunitJavascriptHostCss::CSSStyleDeclaration
63
+ include Celerity::JsxHelper
64
+ end
@@ -0,0 +1,28 @@
1
+ module Celerity
2
+
3
+ class Identifier
4
+ attr_accessor :text
5
+ attr_reader :tag, :attributes
6
+
7
+ def initialize(tag, attributes = {})
8
+ @tag = tag
9
+ @attributes = attributes
10
+ @text = nil
11
+ end
12
+
13
+ def match?(element)
14
+ return false unless @tag == element.getTagName
15
+
16
+ attr_result = @attributes.all? do |key, values|
17
+ values.any? { |val| Util.matches?(element.getAttribute(key.to_s), val) }
18
+ end
19
+
20
+ if @text
21
+ attr_result && Util.matches?(element.asText.strip, @text)
22
+ else
23
+ attr_result
24
+ end
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,15 @@
1
+ module Celerity
2
+ class IgnoringWebConnection < HtmlUnit::Util::FalsifyingWebConnection
3
+
4
+ def initialize(web_client, pattern)
5
+ super(web_client)
6
+ @pattern = pattern
7
+ end
8
+
9
+ def getResponse(request_settings)
10
+ return super unless request_settings.getUrl.toString =~ @pattern
11
+ createWebResponse(request_settings, "", "text/html")
12
+ end
13
+
14
+ end
15
+ end