drnic-celerity 0.0.6.17

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 (230) hide show
  1. data/History.txt +75 -0
  2. data/License.txt +621 -0
  3. data/Manifest.txt +229 -0
  4. data/README.rdoc +78 -0
  5. data/Rakefile +25 -0
  6. data/benchmark/bm_2000_spans.rb +48 -0
  7. data/benchmark/bm_digg.rb +26 -0
  8. data/benchmark/bm_google_images.rb +36 -0
  9. data/benchmark/bm_input_locator.rb +69 -0
  10. data/benchmark/bm_text_input.rb +19 -0
  11. data/benchmark/loader.rb +14 -0
  12. data/celerity.gemspec +40 -0
  13. data/lib/celerity.rb +77 -0
  14. data/lib/celerity/browser.rb +888 -0
  15. data/lib/celerity/clickable_element.rb +73 -0
  16. data/lib/celerity/collections.rb +156 -0
  17. data/lib/celerity/container.rb +779 -0
  18. data/lib/celerity/default_viewer.rb +14 -0
  19. data/lib/celerity/disabled_element.rb +40 -0
  20. data/lib/celerity/element.rb +314 -0
  21. data/lib/celerity/element_collection.rb +107 -0
  22. data/lib/celerity/element_locator.rb +177 -0
  23. data/lib/celerity/elements/button.rb +45 -0
  24. data/lib/celerity/elements/file_field.rb +29 -0
  25. data/lib/celerity/elements/form.rb +23 -0
  26. data/lib/celerity/elements/frame.rb +77 -0
  27. data/lib/celerity/elements/image.rb +76 -0
  28. data/lib/celerity/elements/label.rb +11 -0
  29. data/lib/celerity/elements/link.rb +30 -0
  30. data/lib/celerity/elements/meta.rb +7 -0
  31. data/lib/celerity/elements/non_control_elements.rb +106 -0
  32. data/lib/celerity/elements/option.rb +32 -0
  33. data/lib/celerity/elements/radio_check.rb +115 -0
  34. data/lib/celerity/elements/select_list.rb +142 -0
  35. data/lib/celerity/elements/table.rb +144 -0
  36. data/lib/celerity/elements/table_cell.rb +29 -0
  37. data/lib/celerity/elements/table_elements.rb +42 -0
  38. data/lib/celerity/elements/table_row.rb +48 -0
  39. data/lib/celerity/elements/text_field.rb +169 -0
  40. data/lib/celerity/exception.rb +83 -0
  41. data/lib/celerity/htmlunit.rb +65 -0
  42. data/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
  43. data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  44. data/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
  45. data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  46. data/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
  47. data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  48. data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  49. data/lib/celerity/htmlunit/htmlunit-2.6-SNAPSHOT.jar +0 -0
  50. data/lib/celerity/htmlunit/htmlunit-core-js-2.6-SNAPSHOT.jar +0 -0
  51. data/lib/celerity/htmlunit/nekohtml-1.9.13-20090820.100833-15.jar +0 -0
  52. data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  53. data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  54. data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  55. data/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
  56. data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  57. data/lib/celerity/identifier.rb +11 -0
  58. data/lib/celerity/ignoring_web_connection.rb +15 -0
  59. data/lib/celerity/input_element.rb +25 -0
  60. data/lib/celerity/listener.rb +141 -0
  61. data/lib/celerity/resources/no_viewer.png +0 -0
  62. data/lib/celerity/short_inspect.rb +20 -0
  63. data/lib/celerity/util.rb +91 -0
  64. data/lib/celerity/viewer_connection.rb +89 -0
  65. data/lib/celerity/watir_compatibility.rb +83 -0
  66. data/lib/celerity/xpath_support.rb +48 -0
  67. data/spec/browser_authentication_spec.rb +16 -0
  68. data/spec/browser_spec.rb +300 -0
  69. data/spec/clickable_element_spec.rb +39 -0
  70. data/spec/default_viewer_spec.rb +23 -0
  71. data/spec/element_spec.rb +51 -0
  72. data/spec/filefield_spec.rb +18 -0
  73. data/spec/htmlunit_spec.rb +56 -0
  74. data/spec/index_offset_spec.rb +24 -0
  75. data/spec/listener_spec.rb +142 -0
  76. data/spec/spec_helper.rb +8 -0
  77. data/tasks/benchmark.rake +4 -0
  78. data/tasks/deployment.rake +43 -0
  79. data/tasks/environment.rake +7 -0
  80. data/tasks/fix.rake +25 -0
  81. data/tasks/jar.rake +57 -0
  82. data/tasks/rdoc.rake +4 -0
  83. data/tasks/rspec.rake +43 -0
  84. data/tasks/simple_ci.rake +94 -0
  85. data/tasks/snapshot.rake +22 -0
  86. data/tasks/website.rake +17 -0
  87. data/tasks/yard.rake +9 -0
  88. data/website/benchmarks.html +237 -0
  89. data/website/css/color.css +153 -0
  90. data/website/css/hacks.css +3 -0
  91. data/website/css/layout.css +179 -0
  92. data/website/css/screen.css +5 -0
  93. data/website/css/textmate.css +226 -0
  94. data/website/css/typography.css +72 -0
  95. data/website/gfx/body_bg.gif +0 -0
  96. data/website/gfx/button_bg.jpg +0 -0
  97. data/website/gfx/header_bg.jpg +0 -0
  98. data/website/gfx/header_left.jpg +0 -0
  99. data/website/gfx/header_right.jpg +0 -0
  100. data/website/gfx/nav_bg.jpg +0 -0
  101. data/website/index.html +133 -0
  102. data/website/yard/Celerity.html +50 -0
  103. data/website/yard/Celerity/Area.html +212 -0
  104. data/website/yard/Celerity/Areas.html +103 -0
  105. data/website/yard/Celerity/Browser.html +5594 -0
  106. data/website/yard/Celerity/Button.html +312 -0
  107. data/website/yard/Celerity/Buttons.html +103 -0
  108. data/website/yard/Celerity/CheckBox.html +347 -0
  109. data/website/yard/Celerity/CheckBoxes.html +103 -0
  110. data/website/yard/Celerity/ClickableElement.html +448 -0
  111. data/website/yard/Celerity/Container.html +7676 -0
  112. data/website/yard/Celerity/Dd.html +198 -0
  113. data/website/yard/Celerity/Dds.html +103 -0
  114. data/website/yard/Celerity/DefaultViewer.html +101 -0
  115. data/website/yard/Celerity/DisabledElement.html +252 -0
  116. data/website/yard/Celerity/Div.html +198 -0
  117. data/website/yard/Celerity/Divs.html +103 -0
  118. data/website/yard/Celerity/Dl.html +198 -0
  119. data/website/yard/Celerity/Dls.html +103 -0
  120. data/website/yard/Celerity/Dt.html +198 -0
  121. data/website/yard/Celerity/Dts.html +103 -0
  122. data/website/yard/Celerity/Element.html +1703 -0
  123. data/website/yard/Celerity/ElementCollection.html +725 -0
  124. data/website/yard/Celerity/ElementLocator.html +589 -0
  125. data/website/yard/Celerity/Em.html +198 -0
  126. data/website/yard/Celerity/Ems.html +103 -0
  127. data/website/yard/Celerity/Exception.html +23 -0
  128. data/website/yard/Celerity/Exception/CelerityException.html +32 -0
  129. data/website/yard/Celerity/Exception/MissingWayOfFindingObjectException.html +32 -0
  130. data/website/yard/Celerity/Exception/NavigationException.html +33 -0
  131. data/website/yard/Celerity/Exception/NoValueFoundException.html +33 -0
  132. data/website/yard/Celerity/Exception/ObjectDisabledException.html +33 -0
  133. data/website/yard/Celerity/Exception/ObjectReadOnlyException.html +33 -0
  134. data/website/yard/Celerity/Exception/UnexpectedPageException.html +33 -0
  135. data/website/yard/Celerity/Exception/UnknownCellException.html +33 -0
  136. data/website/yard/Celerity/Exception/UnknownFormException.html +33 -0
  137. data/website/yard/Celerity/Exception/UnknownFrameException.html +33 -0
  138. data/website/yard/Celerity/Exception/UnknownObjectException.html +33 -0
  139. data/website/yard/Celerity/Exception/UnknownRowException.html +33 -0
  140. data/website/yard/Celerity/FileField.html +289 -0
  141. data/website/yard/Celerity/FileFields.html +103 -0
  142. data/website/yard/Celerity/Form.html +284 -0
  143. data/website/yard/Celerity/Forms.html +103 -0
  144. data/website/yard/Celerity/Frame.html +527 -0
  145. data/website/yard/Celerity/Frames.html +103 -0
  146. data/website/yard/Celerity/H1.html +198 -0
  147. data/website/yard/Celerity/H1s.html +103 -0
  148. data/website/yard/Celerity/H2.html +198 -0
  149. data/website/yard/Celerity/H2s.html +103 -0
  150. data/website/yard/Celerity/H3.html +198 -0
  151. data/website/yard/Celerity/H3s.html +103 -0
  152. data/website/yard/Celerity/H4.html +198 -0
  153. data/website/yard/Celerity/H4s.html +103 -0
  154. data/website/yard/Celerity/H5.html +198 -0
  155. data/website/yard/Celerity/H5s.html +103 -0
  156. data/website/yard/Celerity/H6.html +198 -0
  157. data/website/yard/Celerity/H6s.html +103 -0
  158. data/website/yard/Celerity/Hidden.html +285 -0
  159. data/website/yard/Celerity/Hiddens.html +103 -0
  160. data/website/yard/Celerity/Image.html +645 -0
  161. data/website/yard/Celerity/Images.html +103 -0
  162. data/website/yard/Celerity/InputElement.html +271 -0
  163. data/website/yard/Celerity/Label.html +210 -0
  164. data/website/yard/Celerity/Labels.html +103 -0
  165. data/website/yard/Celerity/Li.html +198 -0
  166. data/website/yard/Celerity/Link.html +295 -0
  167. data/website/yard/Celerity/Links.html +103 -0
  168. data/website/yard/Celerity/Lis.html +103 -0
  169. data/website/yard/Celerity/Listener.html +821 -0
  170. data/website/yard/Celerity/Map.html +198 -0
  171. data/website/yard/Celerity/Maps.html +103 -0
  172. data/website/yard/Celerity/Meta.html +196 -0
  173. data/website/yard/Celerity/Metas.html +103 -0
  174. data/website/yard/Celerity/MethodGenerator.html +195 -0
  175. data/website/yard/Celerity/NonControlElement.html +212 -0
  176. data/website/yard/Celerity/Ol.html +198 -0
  177. data/website/yard/Celerity/Ols.html +103 -0
  178. data/website/yard/Celerity/Option.html +348 -0
  179. data/website/yard/Celerity/Options.html +103 -0
  180. data/website/yard/Celerity/P.html +198 -0
  181. data/website/yard/Celerity/Pre.html +198 -0
  182. data/website/yard/Celerity/Pres.html +103 -0
  183. data/website/yard/Celerity/Ps.html +103 -0
  184. data/website/yard/Celerity/Radio.html +339 -0
  185. data/website/yard/Celerity/RadioCheckCommon.html +453 -0
  186. data/website/yard/Celerity/Radios.html +103 -0
  187. data/website/yard/Celerity/SelectList.html +1122 -0
  188. data/website/yard/Celerity/SelectLists.html +103 -0
  189. data/website/yard/Celerity/ShortInspect.html +108 -0
  190. data/website/yard/Celerity/Span.html +198 -0
  191. data/website/yard/Celerity/Spans.html +103 -0
  192. data/website/yard/Celerity/Strong.html +198 -0
  193. data/website/yard/Celerity/Strongs.html +103 -0
  194. data/website/yard/Celerity/Table.html +1287 -0
  195. data/website/yard/Celerity/TableBodies.html +103 -0
  196. data/website/yard/Celerity/TableBody.html +203 -0
  197. data/website/yard/Celerity/TableCell.html +279 -0
  198. data/website/yard/Celerity/TableCells.html +103 -0
  199. data/website/yard/Celerity/TableElement.html +437 -0
  200. data/website/yard/Celerity/TableFooter.html +203 -0
  201. data/website/yard/Celerity/TableFooters.html +103 -0
  202. data/website/yard/Celerity/TableHeader.html +203 -0
  203. data/website/yard/Celerity/TableHeaders.html +103 -0
  204. data/website/yard/Celerity/TableRow.html +478 -0
  205. data/website/yard/Celerity/TableRows.html +103 -0
  206. data/website/yard/Celerity/Tables.html +103 -0
  207. data/website/yard/Celerity/TextField.html +938 -0
  208. data/website/yard/Celerity/TextFields.html +103 -0
  209. data/website/yard/Celerity/Th.html +208 -0
  210. data/website/yard/Celerity/Ul.html +209 -0
  211. data/website/yard/Celerity/Uls.html +103 -0
  212. data/website/yard/Celerity/Util.html +264 -0
  213. data/website/yard/Celerity/VERSION.html +44 -0
  214. data/website/yard/HtmlUnit.html +23 -0
  215. data/website/yard/HtmlUnit/Html.html +23 -0
  216. data/website/yard/HtmlUnit/Util.html +23 -0
  217. data/website/yard/Java/ComGargoylesoftwareHtmlunitHtml/HtmlPage.html +90 -0
  218. data/website/yard/Java/JavaLang/Iterable.html +103 -0
  219. data/website/yard/Java/OrgW3cDom/NamedNodeMap.html +97 -0
  220. data/website/yard/README.txt.html +116 -0
  221. data/website/yard/String.html +103 -0
  222. data/website/yard/all-files.html +22 -0
  223. data/website/yard/all-methods.html +3276 -0
  224. data/website/yard/all-namespaces.html +258 -0
  225. data/website/yard/app.js +18 -0
  226. data/website/yard/index.html +19 -0
  227. data/website/yard/jquery.js +11 -0
  228. data/website/yard/style.css +68 -0
  229. data/website/yard/syntax_highlight.css +21 -0
  230. metadata +307 -0
@@ -0,0 +1,177 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Used internally to locate elements on the page.
5
+ #
6
+
7
+ class ElementLocator
8
+ include Celerity::Exception
9
+ attr_accessor :idents
10
+
11
+
12
+ def initialize(container, element_class)
13
+ container.assert_exists
14
+
15
+ @container = container
16
+ @object = container.object
17
+ @element_class = element_class
18
+ @attributes = @element_class::ATTRIBUTES # could check for 'strict' here?
19
+ @idents = @element_class::TAGS
20
+ @tags = @idents.map { |e| e.tag.downcase }
21
+ end
22
+
23
+ def find_by_conditions(conditions) # TODO: refactor without performance hit
24
+ return nil unless @object # probably means we're on a TextPage (content-type is "text/plain")
25
+
26
+ @condition_idents = []
27
+ attributes = Hash.new { |h, k| h[k] = [] }
28
+ index = 0 # by default, return the first matching element
29
+ text = nil
30
+
31
+ conditions.each do |how, what|
32
+ case how
33
+ when :object
34
+ unless what.is_a?(HtmlUnit::Html::HtmlElement) || what.nil?
35
+ raise ArgumentError, "expected an HtmlUnit::Html::HtmlElement subclass, got #{what.inspect}:#{what.class}"
36
+ end
37
+ return what
38
+ when :xpath
39
+ return find_by_xpath(what)
40
+ when :label
41
+ return find_by_label(what) unless @attributes.include?(:label)
42
+ when :class_name
43
+ how = :class
44
+ when :url
45
+ how = :href
46
+ when :caption
47
+ how = :text
48
+ end
49
+
50
+ if how == :id && conditions.size == 1
51
+ return find_by_id(what)
52
+ elsif @attributes.include?(how = how.to_sym)
53
+ attributes[how] << what
54
+ elsif how == :index
55
+ index = what.to_i - Celerity.index_offset
56
+ elsif how == :text
57
+ text = what
58
+ else
59
+ raise MissingWayOfFindingObjectException, "No how #{how.inspect}"
60
+ end
61
+ end
62
+
63
+ @idents.each do |ident|
64
+ merged = attributes.merge(ident.attributes) { |key, v1, v2| v1 | v2 }
65
+ id = Identifier.new(ident.tag, merged)
66
+ id.text = ident.text || text # «original» identifier takes precedence for :text
67
+ @condition_idents << id
68
+ end
69
+
70
+ if index == 0
71
+ element_by_idents(@condition_idents)
72
+ else
73
+ elements_by_idents(@condition_idents)[index]
74
+ end
75
+
76
+ rescue HtmlUnit::ElementNotFoundException
77
+ nil # for rcov
78
+ end
79
+
80
+ def find_by_id(what)
81
+ case what
82
+ when Regexp
83
+ elements_by_tag_names.find { |elem| elem.getId =~ what }
84
+ when String
85
+ obj = @object.getElementById(what)
86
+ return obj if @tags.include?(obj.getTagName)
87
+
88
+ $stderr.puts "warning: multiple elements with identical id? (#{what.inspect})" if $VERBOSE
89
+ elements_by_tag_names.find { |elem| elem.getId == what }
90
+ else
91
+ raise TypeError, "expected String or Regexp, got #{what.inspect}:#{what.class}"
92
+ end
93
+ end
94
+
95
+ def find_by_xpath(what)
96
+ what = ".#{what}" if what[0].chr == "/"
97
+ @object.getByXPath(what).to_a.first
98
+ end
99
+
100
+ def find_by_label(what)
101
+ obj = elements_by_tag_names(%w[label]).find { |e| matches?(e.asText, what) }
102
+
103
+ return nil unless obj && (ref = obj.getReferencedElement)
104
+ return ref if @tags.include?(ref.getTagName)
105
+
106
+ find_by_id obj.getForAttribute
107
+ end
108
+
109
+ def elements_by_idents(idents = @idents)
110
+ get_by_idents(:select, idents)
111
+ end
112
+
113
+ def element_by_idents(idents = @idents)
114
+ get_by_idents(:find, idents)
115
+ end
116
+
117
+ private
118
+
119
+ def get_by_idents(meth, idents)
120
+ with_nullpointer_retry do
121
+ all_elements.send(meth) do |e|
122
+ next unless @tags.include?(e.getTagName)
123
+ idents.any? { |id| element_matches_ident?(e, id) }
124
+ end
125
+ end
126
+ end
127
+
128
+ def element_matches_ident?(element, ident)
129
+ return false unless ident.tag == element.getTagName
130
+
131
+ attr_result = ident.attributes.all? do |key, values|
132
+ values.any? { |val| matches?(element.getAttribute(key.to_s), val) }
133
+ end
134
+
135
+ if ident.text
136
+ attr_result && matches?(element.asText.strip, ident.text)
137
+ else
138
+ attr_result
139
+ end
140
+ end
141
+
142
+ def elements_by_tag_names(tags = @tags)
143
+ with_nullpointer_retry do
144
+ # HtmlUnit's getHtmlElementsByTagNames won't get elements in the correct
145
+ # order (making :index fail), so we're looping through all elements instead.
146
+ all_elements.select { |elem| tags.include?(elem.getTagName) }
147
+ end
148
+ end
149
+
150
+ def all_elements
151
+ unless @object
152
+ raise %{internal error in #{self.class}: @container=#{@container.inspect} @element_class=#{@element_class.inspect}
153
+ Please report this failure and the code/HTML that caused it at http://github.com/jarib/celerity/issues}
154
+ end
155
+
156
+ @object.getAllHtmlChildElements
157
+ end
158
+
159
+ # HtmlUnit throws NPEs sometimes when we're locating elements
160
+ # Retry seems to work fine.
161
+ def with_nullpointer_retry(max_retries = 3)
162
+ tries = 0
163
+ yield
164
+ rescue java.lang.NullPointerException => e
165
+ raise e if tries >= max_retries
166
+
167
+ tries += 1
168
+ warn "warning: celerity caught #{e} - retry ##{tries}"
169
+ retry
170
+ end
171
+
172
+ def matches?(string, what)
173
+ Regexp === what ? string.strip =~ what : string == what.to_s
174
+ end
175
+
176
+ end # ElementLocator
177
+ end # Celerity
@@ -0,0 +1,45 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Input: Button
5
+ #
6
+ # Class representing button elements.
7
+ #
8
+ # This class covers both <button> and <input type="submit|reset|image|button" /> elements.
9
+ #
10
+
11
+ class Button < InputElement
12
+ TAGS = [ Identifier.new('button'),
13
+ Identifier.new('input', :type => %w[submit reset image button]) ]
14
+
15
+ # Attribute list is a little weird due to this class covering both <button>
16
+ # and <input type="submit|reset|image|button" />
17
+ ATTRIBUTES = ATTRIBUTES | [:type, :disabled, :tabindex, :accesskey, :onfocus, :onblur] | [:src, :usemap, :ismap]
18
+ DEFAULT_HOW = :value
19
+
20
+ #
21
+ # @api private
22
+ #
23
+
24
+ def locate
25
+ # We want the :value attribute to point to the inner HTML for <button> elements,
26
+ # and to the value attribute for <input type="button"> elements.
27
+
28
+ if (val = @conditions[:value])
29
+ button_ident = Identifier.new('button')
30
+ button_ident.text = val
31
+ input_ident = Identifier.new('input', :type => %w[submit reset image button], :value => [val])
32
+
33
+ locator = ElementLocator.new(@container, self.class)
34
+ locator.idents = [button_ident, input_ident]
35
+
36
+ conditions = @conditions.dup
37
+ conditions.delete(:value)
38
+ @object = locator.find_by_conditions(conditions)
39
+ else
40
+ super
41
+ end
42
+ end
43
+
44
+ end # Button
45
+ end # Celerity
@@ -0,0 +1,29 @@
1
+ module Celerity
2
+
3
+ #
4
+ # For fields that accept file uploads
5
+ #
6
+
7
+ class FileField < InputElement
8
+ TAGS = [ Identifier.new('input', :type => %w[file]) ]
9
+ DEFAULT_HOW = :name
10
+
11
+ #
12
+ # Set the file field to the given path
13
+ #
14
+
15
+ def set(path)
16
+ assert_exists
17
+ path = path.to_s
18
+
19
+ @object.setValueAttribute path
20
+
21
+ unless @object.getContentType
22
+ @object.setContentType(Celerity::Util.content_type_for(path))
23
+ end
24
+
25
+ path
26
+ end
27
+
28
+ end # FileField
29
+ end # Celerity
@@ -0,0 +1,23 @@
1
+ module Celerity
2
+ class Form < Element
3
+ include Container
4
+
5
+ TAGS = [Identifier.new('form')]
6
+
7
+ # HTML 4.01 Transitional DTD
8
+ ATTRIBUTES = BASE_ATTRIBUTES | [:action, :method, :enctype, :accept, :name, :onsubmit, :onreset, :target, :'accept-charset']
9
+ DEFAULT_HOW = :name
10
+
11
+ #
12
+ # Submits the form.
13
+ #
14
+ # This method should be avoided - invoke the user interface element that triggers the submit instead.
15
+ #
16
+
17
+ def submit
18
+ assert_exists
19
+ @object.submit(nil)
20
+ end
21
+
22
+ end # Form
23
+ end # Celerity
@@ -0,0 +1,77 @@
1
+ module Celerity
2
+ class Frame < Element
3
+ include Container
4
+ include XpathSupport
5
+
6
+ attr_accessor :page
7
+
8
+ TAGS = [Identifier.new('frame'), Identifier.new('iframe')]
9
+ ATTRIBUTES = BASE_ATTRIBUTES | [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
10
+ DEFAULT_HOW = :name
11
+
12
+ #
13
+ # Override the default locate to handle frame and inline frames.
14
+ # @api private
15
+ #
16
+
17
+ def locate
18
+ super
19
+ if @object
20
+ @inline_frame_object = @object.getEnclosedWindow.getFrameElement
21
+ self.page = @object.getEnclosedPage
22
+ if (frame = self.page.getDocumentElement)
23
+ @object = frame
24
+ end
25
+ end
26
+ end
27
+
28
+ #
29
+ # Override assert_exists to raise UnknownFrameException (for Watir compatibility)
30
+ # @api private
31
+ #
32
+
33
+ def assert_exists
34
+ locate
35
+ unless @object
36
+ raise UnknownFrameException, "unable to locate frame, using #{identifier_string}"
37
+ end
38
+ end
39
+
40
+ #
41
+ # Executes the given JavaScript string in this frame. (Celerity only)
42
+ #
43
+
44
+ def execute_script(source)
45
+ assert_exists
46
+ @page.executeJavaScript(source.to_s).getJavaScriptResult
47
+ end
48
+
49
+ #
50
+ # Updates the brwoser page with the page from this frame's top window.
51
+ # Used internally.
52
+ #
53
+ # @api private
54
+ #
55
+
56
+ def update_page(value)
57
+ @browser.page = value.getEnclosingWindow.getTopWindow.getEnclosedPage
58
+ end
59
+
60
+ def to_s
61
+ assert_exists
62
+ create_string(@inline_frame_object)
63
+ end
64
+
65
+ def method_missing(meth, *args, &blk)
66
+ meth = selector_to_attribute(meth)
67
+ if self.class::ATTRIBUTES.include?(meth)
68
+ assert_exists
69
+ @inline_frame_object.getAttribute(meth.to_s)
70
+ else
71
+ Log.warn "Element\#method_missing calling super with #{meth.inspect}"
72
+ super
73
+ end
74
+ end
75
+
76
+ end # Frame
77
+ end # Celerity
@@ -0,0 +1,76 @@
1
+ module Celerity
2
+
3
+ class Image < Element
4
+ include ClickableElement
5
+
6
+ TAGS = [ Identifier.new('img') ]
7
+
8
+ ATTRIBUTES = BASE_ATTRIBUTES | [:src, :alt, :longdesc, :name, :height, :width, :usemap, :ismap, :align, :border, :hspace, :vspace]
9
+ DEFAULT_HOW = :src
10
+
11
+ #
12
+ # returns the file created date of the image
13
+ #
14
+
15
+ def file_created_date
16
+ assert_exists
17
+ web_response = @object.getWebResponse(true)
18
+ Time.parse(web_response.getResponseHeaderValue("Last-Modified").to_s)
19
+ end
20
+
21
+ #
22
+ # returns the file size of the image in bytes
23
+ #
24
+
25
+ def file_size
26
+ assert_exists
27
+ web_response = @object.getWebResponse(true)
28
+ web_response.getContentAsBytes.length
29
+ end
30
+
31
+ #
32
+ # returns the width in pixels of the image, as a string
33
+ #
34
+
35
+ def width
36
+ assert_exists
37
+ @object.getWidth
38
+ end
39
+
40
+ #
41
+ # returns the height in pixels of the image, as a string
42
+ #
43
+
44
+ def height
45
+ assert_exists
46
+ @object.getHeight
47
+ end
48
+
49
+ #
50
+ # returns true if the image is loaded
51
+ #
52
+
53
+ def loaded?
54
+ assert_exists
55
+ begin
56
+ @object.getImageReader
57
+ true
58
+ rescue
59
+ false
60
+ end
61
+ end
62
+
63
+ #
64
+ # Saves the image to the given file
65
+ #
66
+
67
+ def save(filename)
68
+ assert_exists
69
+ image_reader = @object.getImageReader
70
+ file = java.io.File.new(filename)
71
+ buffered_image = image_reader.read(0);
72
+ javax.imageio.ImageIO.write(buffered_image, image_reader.getFormatName(), file);
73
+ end
74
+
75
+ end # Image
76
+ end # Celerity
@@ -0,0 +1,11 @@
1
+ module Celerity
2
+
3
+ class Label < Element
4
+ include ClickableElement
5
+
6
+ TAGS = [ Identifier.new('label') ]
7
+ ATTRIBUTES = BASE_ATTRIBUTES | [:for, :accesskey, :onfocus, :onblur]
8
+ DEFAULT_HOW = :text
9
+ end
10
+
11
+ end