celerity 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/History.txt +33 -0
  2. data/README.txt +19 -9
  3. data/Rakefile +9 -3
  4. data/lib/celerity.rb +39 -39
  5. data/lib/celerity/browser.rb +538 -153
  6. data/lib/celerity/clickable_element.rb +48 -7
  7. data/lib/celerity/collections.rb +155 -131
  8. data/lib/celerity/container.rb +766 -385
  9. data/lib/celerity/default_viewer.rb +10 -0
  10. data/lib/celerity/disabled_element.rb +19 -2
  11. data/lib/celerity/element.rb +152 -83
  12. data/lib/celerity/element_collection.rb +106 -0
  13. data/lib/celerity/element_locator.rb +89 -66
  14. data/lib/celerity/elements/button.rb +23 -13
  15. data/lib/celerity/elements/file_field.rb +17 -5
  16. data/lib/celerity/elements/form.rb +21 -16
  17. data/lib/celerity/elements/frame.rb +75 -53
  18. data/lib/celerity/elements/image.rb +76 -63
  19. data/lib/celerity/elements/label.rb +4 -2
  20. data/lib/celerity/elements/link.rb +30 -18
  21. data/lib/celerity/elements/meta.rb +6 -0
  22. data/lib/celerity/{non_control_elements.rb → elements/non_control_elements.rb} +106 -76
  23. data/lib/celerity/elements/option.rb +16 -2
  24. data/lib/celerity/elements/radio_check.rb +55 -20
  25. data/lib/celerity/elements/select_list.rb +65 -29
  26. data/lib/celerity/elements/table.rb +141 -94
  27. data/lib/celerity/elements/table_cell.rb +13 -6
  28. data/lib/celerity/elements/{table_body.rb → table_elements.rb} +20 -8
  29. data/lib/celerity/elements/table_row.rb +23 -7
  30. data/lib/celerity/elements/text_field.rb +89 -33
  31. data/lib/celerity/exception.rb +77 -41
  32. data/lib/celerity/extra/method_generator.rb +42 -24
  33. data/lib/celerity/htmlunit.rb +49 -0
  34. data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  35. data/lib/celerity/htmlunit/htmlunit-2.5-SNAPSHOT.jar +0 -0
  36. data/lib/celerity/htmlunit/htmlunit-core-js-2.5-SNAPSHOT.jar +0 -0
  37. data/lib/celerity/htmlunit/nekohtml-1.9.12-20090308.130127-11.jar +0 -0
  38. data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  39. data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  40. data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  41. data/lib/celerity/identifier.rb +3 -2
  42. data/lib/celerity/input_element.rb +5 -5
  43. data/lib/celerity/listener.rb +135 -0
  44. data/lib/celerity/resources/no_viewer.png +0 -0
  45. data/lib/celerity/util.rb +88 -0
  46. data/lib/celerity/version.rb +4 -3
  47. data/lib/celerity/watir_compatibility.rb +35 -25
  48. data/tasks/jar.rake +57 -0
  49. metadata +35 -142
  50. data.tar.gz.sig +0 -0
  51. data/Manifest.txt +0 -150
  52. data/lib/celerity/element_collections.rb +0 -54
  53. data/lib/celerity/element_map.rb +0 -51
  54. data/lib/celerity/elements/table_footer.rb +0 -30
  55. data/lib/celerity/elements/table_header.rb +0 -30
  56. data/lib/celerity/htmlunit/commons-collections-3.2.jar +0 -0
  57. data/lib/celerity/htmlunit/download.sh +0 -23
  58. data/lib/celerity/htmlunit/htmlunit-2.2.jar +0 -0
  59. data/lib/celerity/htmlunit/htmlunit-core-js-2.2.jar +0 -0
  60. data/lib/celerity/htmlunit/nekohtml-1.9.8.jar +0 -0
  61. data/lib/celerity/htmlunit/xalan-2.7.0.jar +0 -0
  62. data/lib/celerity/htmlunit/xml-apis-1.0.b2.jar +0 -0
  63. data/spec/area_spec.rb +0 -97
  64. data/spec/areas_spec.rb +0 -40
  65. data/spec/browser_spec.rb +0 -266
  66. data/spec/button_spec.rb +0 -227
  67. data/spec/buttons_spec.rb +0 -39
  68. data/spec/checkbox_spec.rb +0 -302
  69. data/spec/checkboxes_spec.rb +0 -38
  70. data/spec/div_spec.rb +0 -207
  71. data/spec/divs_spec.rb +0 -39
  72. data/spec/element_spec.rb +0 -79
  73. data/spec/filefield_spec.rb +0 -123
  74. data/spec/filefields_spec.rb +0 -40
  75. data/spec/form_spec.rb +0 -59
  76. data/spec/forms_spec.rb +0 -41
  77. data/spec/frame_spec.rb +0 -121
  78. data/spec/frames_spec.rb +0 -71
  79. data/spec/hidden_spec.rb +0 -127
  80. data/spec/hiddens_spec.rb +0 -39
  81. data/spec/hn_spec.rb +0 -104
  82. data/spec/hns_spec.rb +0 -45
  83. data/spec/html/2000_spans.html +0 -2009
  84. data/spec/html/bug_duplicate_attributes.html +0 -14
  85. data/spec/html/bug_javascript_001.html +0 -11
  86. data/spec/html/form_js_bug.html +0 -11
  87. data/spec/html/forms_with_input_elements.html +0 -114
  88. data/spec/html/frame_1.html +0 -17
  89. data/spec/html/frame_2.html +0 -16
  90. data/spec/html/frames.html +0 -11
  91. data/spec/html/iframes.html +0 -12
  92. data/spec/html/images.html +0 -27
  93. data/spec/html/images/1.gif +0 -0
  94. data/spec/html/images/2.gif +0 -0
  95. data/spec/html/images/3.gif +0 -0
  96. data/spec/html/images/button.jpg +0 -0
  97. data/spec/html/images/circle.jpg +0 -0
  98. data/spec/html/images/map.gif +0 -0
  99. data/spec/html/images/map2.gif +0 -0
  100. data/spec/html/images/minus.gif +0 -0
  101. data/spec/html/images/originaltriangle.jpg +0 -0
  102. data/spec/html/images/plus.gif +0 -0
  103. data/spec/html/images/square.jpg +0 -0
  104. data/spec/html/images/triangle.jpg +0 -0
  105. data/spec/html/invalid_js.html +0 -11
  106. data/spec/html/latin1_text.html +0 -17
  107. data/spec/html/non_control_elements.html +0 -115
  108. data/spec/html/simple_ajax.html +0 -22
  109. data/spec/html/tables.html +0 -119
  110. data/spec/html/utf8_text.html +0 -15
  111. data/spec/htmlunit_spec.rb +0 -26
  112. data/spec/image_spec.rb +0 -220
  113. data/spec/images_spec.rb +0 -39
  114. data/spec/label_spec.rb +0 -79
  115. data/spec/labels_spec.rb +0 -40
  116. data/spec/li_spec.rb +0 -139
  117. data/spec/link_spec.rb +0 -189
  118. data/spec/links_spec.rb +0 -43
  119. data/spec/lis_spec.rb +0 -40
  120. data/spec/map_spec.rb +0 -102
  121. data/spec/maps_spec.rb +0 -40
  122. data/spec/meta_spec.rb +0 -8
  123. data/spec/ol_spec.rb +0 -87
  124. data/spec/ols_spec.rb +0 -40
  125. data/spec/option_spec.rb +0 -154
  126. data/spec/p_spec.rb +0 -171
  127. data/spec/pre_spec.rb +0 -135
  128. data/spec/pres_spec.rb +0 -40
  129. data/spec/ps_spec.rb +0 -40
  130. data/spec/radio_spec.rb +0 -299
  131. data/spec/radios_spec.rb +0 -42
  132. data/spec/select_list_spec.rb +0 -299
  133. data/spec/select_lists_spec.rb +0 -47
  134. data/spec/span_spec.rb +0 -184
  135. data/spec/spans_spec.rb +0 -64
  136. data/spec/spec.opts +0 -1
  137. data/spec/spec_helper.rb +0 -55
  138. data/spec/table_bodies_spec.rb +0 -57
  139. data/spec/table_body_spec.rb +0 -111
  140. data/spec/table_cell_spec.rb +0 -74
  141. data/spec/table_cells_spec.rb +0 -59
  142. data/spec/table_footer_spec.rb +0 -101
  143. data/spec/table_footers_spec.rb +0 -55
  144. data/spec/table_header_spec.rb +0 -101
  145. data/spec/table_headers_spec.rb +0 -55
  146. data/spec/table_row_spec.rb +0 -104
  147. data/spec/table_rows_spec.rb +0 -58
  148. data/spec/table_spec.rb +0 -160
  149. data/spec/tables_spec.rb +0 -42
  150. data/spec/text_field_spec.rb +0 -323
  151. data/spec/text_fields_spec.rb +0 -44
  152. data/spec/ul_spec.rb +0 -88
  153. data/spec/uls_spec.rb +0 -40
  154. data/spec/watir_compatibility_spec.rb +0 -260
  155. data/support/spec_server.rb +0 -73
  156. data/tasks/rspec.rake +0 -30
  157. data/tasks/specserver.rake +0 -21
  158. metadata.gz.sig +0 -0
@@ -1,33 +1,46 @@
1
1
  module Celerity
2
-
2
+
3
+ #
3
4
  # Used internally to locate elements on the page.
5
+ #
6
+
4
7
  class ElementLocator
5
8
  include Celerity::Exception
6
9
  attr_accessor :idents
7
-
8
-
9
- def initialize(object, element_class)
10
- @object = object
10
+
11
+
12
+ def initialize(container, element_class)
13
+ container.assert_exists
14
+
15
+ @container = container
16
+ @object = container.object
11
17
  @element_class = element_class
12
- @attributes = @element_class::ATTRIBUTES # could check for 'strict' here?
13
- @idents = @element_class::TAGS
14
- @tags = @idents.map { |e| e.tag.downcase }
18
+ @attributes = @element_class::ATTRIBUTES # could check for 'strict' here?
19
+ @idents = @element_class::TAGS
20
+ @tags = @idents.map { |e| e.tag.downcase }
15
21
  end
16
22
 
17
- def find_by_conditions(conditions)
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
+
18
26
  @condition_idents = []
19
27
  attributes = Hash.new { |h, k| h[k] = [] }
20
28
  index = 0 # by default, return the first matching element
21
- text = nil
22
-
29
+ text = nil
30
+
23
31
  conditions.each do |how, what|
24
32
  case how
25
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
26
37
  return what
27
38
  when :id
28
39
  return find_by_id(what)
29
40
  when :xpath
30
41
  return find_by_xpath(what)
42
+ when :label
43
+ return find_by_label(what) unless @attributes.include?(:label)
31
44
  when :class_name
32
45
  how = :class
33
46
  when :url
@@ -35,30 +48,25 @@ module Celerity
35
48
  when :caption
36
49
  how = :text
37
50
  end
38
-
39
- if @attributes.include?(how)
40
- attributes[how] << what
51
+
52
+ if @attributes.include?(how = how.to_sym)
53
+ attributes[how] << what
41
54
  elsif how == :index
42
- index = what.to_i - 1
55
+ index = what.to_i - INDEX_OFFSET
43
56
  elsif how == :text
44
57
  text = what
45
58
  else
46
59
  raise MissingWayOfFindingObjectException, "No how #{how.inspect}"
47
60
  end
48
-
49
61
  end
50
62
 
51
63
  @idents.each do |ident|
52
- merged = attributes.merge(ident.attributes) do |key, v1, v2|
53
- v1 | v2
54
- end
55
-
64
+ merged = attributes.merge(ident.attributes) { |key, v1, v2| v1 | v2 }
56
65
  id = Identifier.new(ident.tag, merged)
57
- # «original» identifier takes precedence for :text
58
- id.text = ident.text || text
66
+ id.text = ident.text || text # «original» identifier takes precedence for :text
59
67
  @condition_idents << id
60
68
  end
61
-
69
+
62
70
  if index == 0
63
71
  element_by_idents(@condition_idents)
64
72
  else
@@ -68,80 +76,95 @@ module Celerity
68
76
  rescue HtmlUnit::ElementNotFoundException
69
77
  nil # for rcov
70
78
  end
71
-
79
+
72
80
  def find_by_id(what)
73
81
  case what
74
82
  when Regexp
75
- elements_by_tag_names.find { |elem| elem.getIdAttribute =~ what }
83
+ elements_by_tag_names.find { |elem| elem.getId =~ what }
76
84
  when String
77
85
  obj = @object.getHtmlElementById(what)
78
- if @tags.include?(obj.getTagName)
79
- obj
80
- else
81
- $stderr.puts "warning: multiple elements with identical id (#{what.inspect})? " if $VERBOSE
82
- elements_by_tag_names.find { |elem| elem.getIdAttribute == what }
83
- end
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 }
84
90
  else
85
- raise ArgumentError, "Argument #{what.inspect} should be a String or Regexp"
91
+ raise TypeError, "expected String or Regexp, got #{what.inspect}:#{what.class}"
86
92
  end
87
93
  end
88
-
94
+
89
95
  def find_by_xpath(what)
90
- what = ".#{what}" if what[0] == ?/
96
+ what = ".#{what}" if what[0].chr == "/"
91
97
  @object.getByXPath(what).to_a.first
92
98
  end
93
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
+
94
109
  def elements_by_idents(idents = nil)
95
110
  get_by_idents(:select, idents || @idents)
96
111
  end
97
-
112
+
98
113
  def element_by_idents(idents = nil)
99
114
  get_by_idents(:find, idents || @idents)
100
115
  end
101
116
 
102
- private
117
+ private
103
118
 
104
119
  def get_by_idents(meth, idents)
105
- @object.getAllHtmlChildElements.iterator.to_a.send(meth) do |e|
106
- if @tags.include?(e.getTagName)
107
- idents.any? do |ident|
108
- next unless ident.tag == e.getTagName
109
-
110
- attr_result = ident.attributes.all? do |key, value|
111
- value.any? { |val| matches?(e.getAttributeValue(key.to_s), val) }
112
- end
113
-
114
- if ident.text
115
- attr_result && matches?(e.asText, ident.text)
116
- else
117
- attr_result
118
- end
119
- end
120
+ with_nullpointer_retry do
121
+ @object.getAllHtmlChildElements.send(meth) do |e|
122
+ next unless @tags.include?(e.getTagName)
123
+ idents.any? { |id| element_matches_ident?(e, id) }
120
124
  end
121
125
  end
122
126
  end
123
127
 
124
- def matches?(string, what)
125
- Regexp === what ? string.match(what) : string == what.to_s
126
- end
128
+ def element_matches_ident?(element, ident)
129
+ return false unless ident.tag == element.getTagName
127
130
 
128
- def elements_by_tag_names
129
- tries = 0
130
- # HtmlUnit's getHtmlElementsByTagNames won't get elements in the correct order, making :index fail
131
- @object.getAllHtmlChildElements.iterator.to_a.select do |elem|
132
- @tags.include?(elem.getTagName)
131
+ attr_result = ident.attributes.all? do |key, values|
132
+ values.any? { |val| matches?(element.getAttributeValue(key.to_s), val) }
133
133
  end
134
- # workaround for HtmlUnit bug?
135
- rescue java.lang.NullPointerException => e
136
- $stderr.puts "warning: celerity caught #{e}"
137
- if tries < 2
138
- tries += 1
139
- retry
134
+
135
+ if ident.text
136
+ attr_result && matches?(element.asText.strip, ident.text)
140
137
  else
141
- raise e
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 using getAllHtmlChildElements instead.
146
+ @object.getAllHtmlChildElements.select do |elem|
147
+ tags.include?(elem.getTagName)
148
+ end
142
149
  end
143
150
  end
144
151
 
152
+ # HtmlUnit throws NPEs sometimes when we're locating elements
153
+ # Retry seems to work fine.
154
+ def with_nullpointer_retry(max_retries = 3)
155
+ tries = 0
156
+ yield
157
+ rescue java.lang.NullPointerException => e
158
+ raise e if tries >= max_retries
159
+
160
+ tries += 1
161
+ $stderr.puts "warning: celerity caught #{e} - retry ##{tries}"
162
+ retry
163
+ end
164
+
165
+ def matches?(string, what)
166
+ Regexp === what ? string.strip =~ what : string == what.to_s
167
+ end
145
168
 
146
169
  end # ElementLocator
147
170
  end # Celerity
@@ -1,25 +1,36 @@
1
1
  module Celerity
2
- #
2
+
3
+ #
3
4
  # Input: Button
4
5
  #
5
6
  # Class representing button elements
6
7
  #
8
+
7
9
  class Button < InputElement
8
- TAGS = [ Identifier.new('button'),
9
- Identifier.new('input', :type => %w(submit reset image button)) ]
10
- # A little wierd attribute list due to button being both <button> and <input type="submit|reset|image|button" />
10
+ TAGS = [ Identifier.new('button'),
11
+ Identifier.new('input', :type => %w[submit reset image button]) ]
12
+
13
+ # Attribute list is a little weird due to this class covering both <button>
14
+ # and <input type="submit|reset|image|button" />
11
15
  ATTRIBUTES = BASE_ATTRIBUTES | [:type, :disabled, :tabindex, :accesskey, :onfocus, :onblur] | [:src, :usemap, :ismap]
12
16
  DEFAULT_HOW = :value
13
17
 
18
+ #
19
+ # @api private
20
+ #
21
+
14
22
  def locate
15
- # ugly..
16
- # this is done to make <button> and <input>-buttons look similar
23
+ # We want the :value attribute to point to the inner HTML for <button> elements,
24
+ # and to the value attribute for <input type="button"> elements.
25
+
17
26
  if (val = @conditions[:value])
18
- locator = ElementLocator.new(@container.object, self.class)
19
- button_ident = Identifier.new('button')
27
+ button_ident = Identifier.new('button')
20
28
  button_ident.text = val
21
- input_ident = Identifier.new('input', :type => %w(submit reset image button), :value => [val])
29
+ input_ident = Identifier.new('input', :type => %w[submit reset image button], :value => [val])
30
+
31
+ locator = ElementLocator.new(@container, self.class)
22
32
  locator.idents = [button_ident, input_ident]
33
+
23
34
  conditions = @conditions.dup
24
35
  conditions.delete(:value)
25
36
  @object = locator.find_by_conditions(conditions)
@@ -27,7 +38,6 @@ module Celerity
27
38
  super
28
39
  end
29
40
  end
30
-
31
- end
32
-
33
- end
41
+
42
+ end # Button
43
+ end # Celerity
@@ -1,13 +1,25 @@
1
1
  module Celerity
2
+
3
+ #
2
4
  # For fields that accept file uploads
5
+ #
6
+
3
7
  class FileField < InputElement
4
- TAGS = [ Identifier.new('input', :type => %w(file)) ]
8
+ TAGS = [ Identifier.new('input', :type => %w[file]) ]
5
9
  DEFAULT_HOW = :name
6
-
10
+
11
+ #
7
12
  # Set the file field to the given path
13
+ #
14
+
8
15
  def set(path)
9
16
  assert_exists
10
- @object.setValueAttribute(path.to_s)
17
+ path = path.to_s
18
+ @container.update_page @object.setValueAttribute(path)
19
+ unless @object.getContentType
20
+ @object.setContentType(Celerity::Util.content_type_for(path))
21
+ end
11
22
  end
12
- end
13
- end
23
+
24
+ end # FileField
25
+ end # Celerity
@@ -1,16 +1,21 @@
1
- module Celerity
2
- class Form < Element
3
- include Container
4
- TAGS = [Identifier.new('form')]
5
- # HTML 4.01 Transitional DTD
6
- ATTRIBUTES = BASE_ATTRIBUTES | [:action, :method, :enctype, :accept, :name, :onsubmit, :onreset, :target, :'accept-charset']
7
- DEFAULT_HOW = :name
8
-
9
- # Submits the form.
10
- def submit
11
- assert_exists
12
- @container.update_page @object.submit(nil)
13
- end
14
-
15
- end
16
- end
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
+
15
+ def submit
16
+ assert_exists
17
+ @container.update_page @object.submit(nil)
18
+ end
19
+
20
+ end # Form
21
+ end # Celerity
@@ -1,53 +1,75 @@
1
- module Celerity
2
- class Frame < Element
3
- include Container
4
- attr_accessor :page
5
-
6
- TAGS = [Identifier.new('frame'), Identifier.new('iframe')]
7
- ATTRIBUTES = BASE_ATTRIBUTES | [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
8
- DEFAULT_HOW = :name
9
-
10
- # Override the default locate to handle frame and inline frames.
11
- # @api internal
12
- def locate
13
- super
14
- if @object
15
- @inline_frame_object = @object.getEnclosedWindow.getFrameElement
16
- if (frame = @object.getEnclosedPage.getDocumentElement)
17
- @object = frame
18
- end
19
- end
20
- end
21
-
22
- # Override assert_exists to raise UnknownFrameException (for Watir compatibility)
23
- # @api internal
24
- def assert_exists
25
- locate unless @object
26
- unless @object
27
- raise UnknownFrameException, "unable to locate frame, using #{identifier_string}"
28
- end
29
- end
30
-
31
- def update_page(value)
32
- @page_container.page = value.getEnclosingWindow.getTopWindow.getEnclosedPage
33
- end
34
-
35
- def to_s
36
- assert_exists
37
- create_string(@inline_frame_object)
38
- end
39
-
40
- def method_missing(meth, *args, &blk)
41
- meth = selector_to_attribute(meth)
42
- if self.class::ATTRIBUTES.include?(meth)
43
- assert_exists
44
- @inline_frame_object.getAttributeValue(meth.to_s)
45
- else
46
- Log.warn "Element\#method_missing calling super with #{meth.inspect}"
47
- super
48
- end
49
- end
50
-
51
- end
52
-
53
- end
1
+ module Celerity
2
+ class Frame < Element
3
+ include Container
4
+ attr_accessor :page
5
+
6
+ TAGS = [Identifier.new('frame'), Identifier.new('iframe')]
7
+ ATTRIBUTES = BASE_ATTRIBUTES | [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
8
+ DEFAULT_HOW = :name
9
+
10
+ #
11
+ # Override the default locate to handle frame and inline frames.
12
+ # @api private
13
+ #
14
+
15
+ def locate
16
+ super
17
+ if @object
18
+ @inline_frame_object = @object.getEnclosedWindow.getFrameElement
19
+ self.page = @object.getEnclosedPage
20
+ if (frame = self.page.getDocumentElement)
21
+ @object = frame
22
+ end
23
+ end
24
+ end
25
+
26
+ #
27
+ # Override assert_exists to raise UnknownFrameException (for Watir compatibility)
28
+ # @api private
29
+ #
30
+
31
+ def assert_exists
32
+ locate
33
+ unless @object
34
+ raise UnknownFrameException, "unable to locate frame, using #{identifier_string}"
35
+ end
36
+ end
37
+
38
+ #
39
+ # Executes the given JavaScript string in this frame. (Celerity only)
40
+ #
41
+
42
+ def execute_script(source)
43
+ assert_exists
44
+ @page.executeJavaScript(source.to_s).getJavaScriptResult
45
+ end
46
+
47
+ #
48
+ # Updates the brwoser page with the page from this frame's top window.
49
+ # Used internally.
50
+ #
51
+ # @api private
52
+ #
53
+
54
+ def update_page(value)
55
+ @browser.page = value.getEnclosingWindow.getTopWindow.getEnclosedPage
56
+ end
57
+
58
+ def to_s
59
+ assert_exists
60
+ create_string(@inline_frame_object)
61
+ end
62
+
63
+ def method_missing(meth, *args, &blk)
64
+ meth = selector_to_attribute(meth)
65
+ if self.class::ATTRIBUTES.include?(meth)
66
+ assert_exists
67
+ @inline_frame_object.getAttributeValue(meth.to_s)
68
+ else
69
+ Log.warn "Element\#method_missing calling super with #{meth.inspect}"
70
+ super
71
+ end
72
+ end
73
+
74
+ end # Frame
75
+ end # Celerity