celerity 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +621 -0
  3. data/README.txt +58 -0
  4. data/Rakefile +4 -0
  5. data/lib/celerity.rb +47 -0
  6. data/lib/celerity/clickable_element.rb +11 -0
  7. data/lib/celerity/collections.rb +99 -0
  8. data/lib/celerity/container.rb +369 -0
  9. data/lib/celerity/disabled_element.rb +20 -0
  10. data/lib/celerity/element.rb +114 -0
  11. data/lib/celerity/element_collections.rb +67 -0
  12. data/lib/celerity/elements/button.rb +13 -0
  13. data/lib/celerity/elements/file_field.rb +12 -0
  14. data/lib/celerity/elements/form.rb +15 -0
  15. data/lib/celerity/elements/frame.rb +44 -0
  16. data/lib/celerity/elements/image.rb +70 -0
  17. data/lib/celerity/elements/label.rb +10 -0
  18. data/lib/celerity/elements/link.rb +13 -0
  19. data/lib/celerity/elements/radio_check.rb +59 -0
  20. data/lib/celerity/elements/select_list.rb +84 -0
  21. data/lib/celerity/elements/table.rb +94 -0
  22. data/lib/celerity/elements/table_body.rb +38 -0
  23. data/lib/celerity/elements/table_cell.rb +30 -0
  24. data/lib/celerity/elements/table_row.rb +34 -0
  25. data/lib/celerity/elements/text_field.rb +80 -0
  26. data/lib/celerity/exception.rb +48 -0
  27. data/lib/celerity/htmlunit/commons-codec-1.3.jar +0 -0
  28. data/lib/celerity/htmlunit/commons-collections-3.2.jar +0 -0
  29. data/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
  30. data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  31. data/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
  32. data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  33. data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  34. data/lib/celerity/htmlunit/htmlunit-2.2-SNAPSHOT.jar +0 -0
  35. data/lib/celerity/htmlunit/js-1.7R1.jar +0 -0
  36. data/lib/celerity/htmlunit/nekohtml-1.9.7.jar +0 -0
  37. data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  38. data/lib/celerity/htmlunit/xalan-2.7.0.jar +0 -0
  39. data/lib/celerity/htmlunit/xercesImpl-2.8.1.jar +0 -0
  40. data/lib/celerity/htmlunit/xml-apis-1.0.b2.jar +0 -0
  41. data/lib/celerity/ie.rb +126 -0
  42. data/lib/celerity/input_element.rb +29 -0
  43. data/lib/celerity/non_control_elements.rb +50 -0
  44. data/lib/celerity/version.rb +9 -0
  45. data/setup.rb +1585 -0
  46. data/spec/area_spec.rb +79 -0
  47. data/spec/areas_spec.rb +41 -0
  48. data/spec/button_spec.rb +171 -0
  49. data/spec/buttons_spec.rb +40 -0
  50. data/spec/checkbox_spec.rb +259 -0
  51. data/spec/checkboxes_spec.rb +39 -0
  52. data/spec/div_spec.rb +174 -0
  53. data/spec/divs_spec.rb +40 -0
  54. data/spec/element_spec.rb +29 -0
  55. data/spec/filefield_spec.rb +110 -0
  56. data/spec/filefields_spec.rb +41 -0
  57. data/spec/form_spec.rb +53 -0
  58. data/spec/forms_spec.rb +42 -0
  59. data/spec/frame_spec.rb +103 -0
  60. data/spec/hidden_spec.rb +105 -0
  61. data/spec/hiddens_spec.rb +40 -0
  62. data/spec/html/forms_with_input_elements.html +107 -0
  63. data/spec/html/frame_1.html +17 -0
  64. data/spec/html/frame_2.html +16 -0
  65. data/spec/html/frames.html +11 -0
  66. data/spec/html/iframes.html +12 -0
  67. data/spec/html/images.html +24 -0
  68. data/spec/html/images/1.gif +0 -0
  69. data/spec/html/images/2.gif +0 -0
  70. data/spec/html/images/3.gif +0 -0
  71. data/spec/html/images/button.jpg +0 -0
  72. data/spec/html/images/circle.jpg +0 -0
  73. data/spec/html/images/map.gif +0 -0
  74. data/spec/html/images/map2.gif +0 -0
  75. data/spec/html/images/minus.gif +0 -0
  76. data/spec/html/images/originaltriangle.jpg +0 -0
  77. data/spec/html/images/plus.gif +0 -0
  78. data/spec/html/images/square.jpg +0 -0
  79. data/spec/html/images/triangle.jpg +0 -0
  80. data/spec/html/non_control_elements.html +85 -0
  81. data/spec/html/tables.html +119 -0
  82. data/spec/ie_spec.rb +146 -0
  83. data/spec/image_spec.rb +210 -0
  84. data/spec/images_spec.rb +39 -0
  85. data/spec/label_spec.rb +65 -0
  86. data/spec/labels_spec.rb +41 -0
  87. data/spec/li_spec.rb +114 -0
  88. data/spec/link_spec.rb +147 -0
  89. data/spec/links_spec.rb +43 -0
  90. data/spec/lis_spec.rb +40 -0
  91. data/spec/map_spec.rb +83 -0
  92. data/spec/maps_spec.rb +41 -0
  93. data/spec/p_spec.rb +140 -0
  94. data/spec/pre_spec.rb +110 -0
  95. data/spec/pres_spec.rb +41 -0
  96. data/spec/ps_spec.rb +40 -0
  97. data/spec/radio_spec.rb +260 -0
  98. data/spec/radios_spec.rb +43 -0
  99. data/spec/select_list_spec.rb +286 -0
  100. data/spec/select_lists_spec.rb +47 -0
  101. data/spec/span_spec.rb +156 -0
  102. data/spec/spans_spec.rb +65 -0
  103. data/spec/spec.opts +1 -0
  104. data/spec/spec_helper.rb +90 -0
  105. data/spec/table_bodies.rb +40 -0
  106. data/spec/table_bodies_spec.rb +42 -0
  107. data/spec/table_body_spec.rb +72 -0
  108. data/spec/table_cell_spec.rb +61 -0
  109. data/spec/table_cells_spec.rb +60 -0
  110. data/spec/table_row_spec.rb +59 -0
  111. data/spec/table_rows_spec.rb +57 -0
  112. data/spec/table_spec.rb +111 -0
  113. data/spec/tables_spec.rb +42 -0
  114. data/spec/text_field_spec.rb +234 -0
  115. data/spec/text_fields_spec.rb +45 -0
  116. data/tasks/environment.rake +7 -0
  117. data/tasks/rspec.rake +23 -0
  118. data/tasks/simple_ci.rake +94 -0
  119. data/tasks/testserver.rake +17 -0
  120. metadata +174 -0
@@ -0,0 +1,58 @@
1
+ = Celerity
2
+
3
+ * http://celerity.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Celerity is a JRuby/RJB wrapper around the HtmlUnit Java library (http://htmlunit.sourceforge.net/).
8
+ The goal of the project is to implement the Watir API (http://wtf.rubyforge.org/) on top of HtmlUnit.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * FIX (list of features or problems)
13
+
14
+ == SYNOPSIS:
15
+
16
+ require 'rubygems'
17
+ require 'celerity'
18
+
19
+ browser = Celerity::IE.new
20
+ browser.goto("google.com")
21
+ browser.text_field(:name, 'q').set("celerity")
22
+ browser.button(:name, 'btnG').submit
23
+
24
+ == REQUIREMENTS:
25
+
26
+ * JRuby 1.1
27
+
28
+ or
29
+
30
+ * Ruby Java Bridge (on MRI)
31
+
32
+ NOTE: RJB currently has problems with threading. Use JRuby if you want to run your tests concurrently.
33
+
34
+ == INSTALL:
35
+
36
+ * jruby -S gem install celerity
37
+
38
+ or
39
+
40
+ * (sudo) gem install rjb celerity
41
+
42
+ == LICENSE:
43
+
44
+ Celerity - JRuby wrapper for HtmlUnit
45
+ Copyright (c) 2008 FinnTech AS
46
+
47
+ This program is free software: you can redistribute it and/or modify
48
+ it under the terms of the GNU General Public License as published by
49
+ the Free Software Foundation, either version 3 of the License, or
50
+ (at your option) any later version.
51
+
52
+ This program is distributed in the hope that it will be useful,
53
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55
+ GNU General Public License for more details.
56
+
57
+ You should have received a copy of the GNU General Public License
58
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,47 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ HTMLUNIT_JARS = Dir[File.dirname(__FILE__) + '/celerity/htmlunit/*.jar']
4
+
5
+ if RUBY_PLATFORM =~ /java/
6
+ require 'java'
7
+ HTMLUNIT_JARS.each { |jar| require(jar) }
8
+
9
+ module HtmlUnit
10
+ include_package 'com.gargoylesoftware.htmlunit'
11
+ end
12
+ ArrayList = java.util.ArrayList
13
+ else
14
+ require "rjb"
15
+ require "watir"
16
+ Rjb::load(HTMLUNIT_JARS.join(";"))
17
+ module HtmlUnit
18
+ WebClient = Rjb::import('com.gargoylesoftware.htmlunit.WebClient')
19
+ BrowserVersion = Rjb::import('com.gargoylesoftware.htmlunit.BrowserVersion')
20
+ end
21
+ end
22
+
23
+ module Celerity; end
24
+ require "celerity/version"
25
+ require "celerity/exception"
26
+ require "celerity/clickable_element"
27
+ require "celerity/disabled_element"
28
+ require "celerity/element_collections"
29
+ require "celerity/collections"
30
+ require "celerity/container"
31
+ require "celerity/element"
32
+ require "celerity/input_element"
33
+ require "celerity/non_control_elements"
34
+ Dir[File.dirname(__FILE__) + "/celerity/elements/*.rb"].each { |f| require(f) }
35
+ require "celerity/ie"
36
+
37
+
38
+ require "logger"
39
+ require "uri"
40
+ require "pp"
41
+ require "time"
42
+
43
+ Log = Logger.new($DEBUG ? $stderr : nil)
44
+ Log.level = Logger::DEBUG
45
+ # undefine deprecated methods to use them for Element attributes
46
+ Object.send :undef_method, :id
47
+ Object.send :undef_method, :type
@@ -0,0 +1,11 @@
1
+ module Celerity
2
+ module ClickableElement
3
+
4
+ def click
5
+ assert_exists
6
+ assert_enabled
7
+ @container.update_page(@object.click)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,99 @@
1
+ module Celerity
2
+
3
+ class Buttons < ElementCollections
4
+ def element_class; Button; end
5
+ end
6
+
7
+ class FileFields < ElementCollections
8
+ def element_class; FileField; end
9
+ end
10
+
11
+ class CheckBoxes < ElementCollections
12
+ def element_class; CheckBox; end
13
+ private
14
+ def iterator_object(i)
15
+ element_class.new(@container, :index, i+1, nil)
16
+ end
17
+ end
18
+
19
+ class Radios < ElementCollections
20
+ def element_class; Radio; end
21
+ private
22
+ def iterator_object(i)
23
+ element_class.new(@container, :index, i+1, nil)
24
+ end
25
+ end
26
+
27
+ class SelectLists < ElementCollections
28
+ def element_class; SelectList; end
29
+ end
30
+
31
+ class Links < ElementCollections
32
+ def element_class; Link; end
33
+ end
34
+
35
+ class Lis < ElementCollections
36
+ def element_class; Li; end
37
+ end
38
+
39
+ class Maps < ElementCollections
40
+ def element_class; Map; end
41
+ end
42
+
43
+ class Areas < ElementCollections
44
+ def element_class; Area; end
45
+ end
46
+
47
+ class Images < ElementCollections
48
+ def element_class; Image; end
49
+ end
50
+
51
+ class TextFields < ElementCollections
52
+ def element_class; TextField; end
53
+ end
54
+
55
+ class Hiddens < ElementCollections
56
+ def element_class; Hidden; end
57
+ end
58
+
59
+ class Tables < ElementCollections
60
+ def element_class; Table; end
61
+ end
62
+
63
+ class TableBodies < ElementCollections
64
+ def element_class; TableBody; end
65
+ end
66
+
67
+ class TableRows < ElementCollections
68
+ def element_class; TableRow; end
69
+ end
70
+
71
+ class TableCells < ElementCollections
72
+ def element_class; TableCell; end
73
+ end
74
+
75
+ class Labels < ElementCollections
76
+ def element_class; Label; end
77
+ end
78
+
79
+ class Pres < ElementCollections
80
+ def element_class; Pre; end
81
+ end
82
+
83
+ class Ps < ElementCollections
84
+ def element_class; P; end
85
+ end
86
+
87
+ class Spans < ElementCollections
88
+ def element_class; Span; end
89
+ end
90
+
91
+ class Divs < ElementCollections
92
+ def element_class; Div; end
93
+ end
94
+
95
+ class Forms < ElementCollections
96
+ def element_class; Form; end
97
+ end
98
+
99
+ end
@@ -0,0 +1,369 @@
1
+ module Celerity
2
+ module Container
3
+ include Celerity::Exception
4
+
5
+ attr_accessor :page_container
6
+
7
+ def set_container(container)
8
+ @container = container
9
+ @page_container = container.page_container
10
+ end
11
+
12
+ def update_page(page)
13
+ @page_container.set_page(page)
14
+ end
15
+
16
+ def contains_text(expected_text)
17
+ assert_exists
18
+ case expected_text
19
+ when Regexp
20
+ text().match(expected_text)
21
+ when String
22
+ text().index(expected_text)
23
+ else
24
+ raise ArgumentError, "Argument #{expected_text.inspect} should be a String or Regexp."
25
+ end
26
+ end
27
+
28
+ def frame(*args)
29
+ assert_exists
30
+ Frame.new(self, *args)
31
+ end
32
+
33
+ def table(*args)
34
+ assert_exists
35
+ Table.new(self, *args)
36
+ end
37
+ def tables
38
+ assert_exists
39
+ Tables.new(self)
40
+ end
41
+
42
+ def cell(*args)
43
+ assert_exists
44
+ TableCell.new(self, *args)
45
+ end
46
+ def cells
47
+ assert_exists
48
+ TableCells.new(self)
49
+ end
50
+
51
+ def row(*args)
52
+ assert_exists
53
+ TableRow.new(self, *args)
54
+ end
55
+ def rows
56
+ assert_exists
57
+ TableRows.new(self)
58
+ end
59
+
60
+ def button(*args)
61
+ assert_exists
62
+ Button.new(self, *args)
63
+ end
64
+ def buttons
65
+ assert_exists
66
+ Buttons.new(self)
67
+ end
68
+
69
+ def file_field(*args)
70
+ assert_exists
71
+ FileField.new(self, *args)
72
+ end
73
+ def file_fields
74
+ assert_exists
75
+ FileFields.new(self)
76
+ end
77
+
78
+ def text_field(*args)
79
+ assert_exists
80
+ TextField.new(self, *args)
81
+ end
82
+ def text_fields
83
+ assert_exists
84
+ TextFields.new(self)
85
+ end
86
+
87
+ def hidden(*args)
88
+ assert_exists
89
+ Hidden.new(self, *args)
90
+ end
91
+ def hiddens
92
+ assert_exists
93
+ Hiddens.new(self)
94
+ end
95
+
96
+ def select_list(*args)
97
+ assert_exists
98
+ SelectList.new(self, *args)
99
+ end
100
+ def select_lists
101
+ assert_exists
102
+ SelectLists.new(self)
103
+ end
104
+
105
+ def check_box(how, what, value = nil)
106
+ assert_exists
107
+ CheckBox.new(self, how, what, ["checkbox"], value)
108
+ end
109
+ alias_method :checkbox, :check_box
110
+ alias_method :checkBox, :check_box
111
+
112
+ def checkboxes
113
+ assert_exists
114
+ CheckBoxes.new(self)
115
+ end
116
+
117
+ def radio(how, what, value = nil)
118
+ assert_exists
119
+ Radio.new(self, how, what, ["radio"], value)
120
+ end
121
+ def radios
122
+ assert_exists
123
+ Radios.new(self)
124
+ end
125
+
126
+ def link(*args)
127
+ assert_exists
128
+ Link.new(self, *args)
129
+ end
130
+
131
+ def links
132
+ assert_exists
133
+ Links.new(self)
134
+ end
135
+
136
+ def li(*args)
137
+ assert_exists
138
+ Li.new(self, *args)
139
+ end
140
+ def lis
141
+ assert_exists
142
+ Lis.new(self)
143
+ end
144
+
145
+ def map(*args)
146
+ assert_exists
147
+ Map.new(self, *args)
148
+ end
149
+ def maps
150
+ assert_exists
151
+ Maps.new(self)
152
+ end
153
+
154
+ def area(*args)
155
+ assert_exists
156
+ Area.new(self, *args)
157
+ end
158
+ def areas
159
+ assert_exists
160
+ Areas.new(self)
161
+ end
162
+
163
+ def image(*args)
164
+ assert_exists
165
+ Image.new(self, *args)
166
+ end
167
+ def images
168
+ assert_exists
169
+ Images.new(self)
170
+ end
171
+
172
+ #TODO: Popup method here?
173
+
174
+ def div(*args)
175
+ assert_exists
176
+ Div.new(self, *args)
177
+ end
178
+
179
+ def divs
180
+ assert_exists
181
+ Divs.new(self)
182
+ end
183
+
184
+ def form(*args)
185
+ assert_exists
186
+ Form.new(self, *args)
187
+ end
188
+ def forms
189
+ assert_exists
190
+ Forms.new(self)
191
+ end
192
+
193
+ def span(*args)
194
+ assert_exists
195
+ Span.new(self, *args)
196
+ end
197
+ def spans
198
+ assert_exists
199
+ Spans.new(self)
200
+ end
201
+
202
+ def p(*args)
203
+ assert_exists
204
+ P.new(self, *args)
205
+ end
206
+ def ps
207
+ assert_exists
208
+ Ps.new(self)
209
+ end
210
+
211
+ def pre(*args)
212
+ assert_exists
213
+ Pre.new(self, *args)
214
+ end
215
+ def pres
216
+ assert_exists
217
+ Pres.new(self)
218
+ end
219
+
220
+ def label(*args)
221
+ assert_exists
222
+ Label.new(self, *args)
223
+ end
224
+ def labels
225
+ assert_exists
226
+ Labels.new(self)
227
+ end
228
+
229
+ #
230
+ # Locator Methods
231
+ #
232
+
233
+ # Returns the specified ole object for input elements on a web page.
234
+ #
235
+ # This method is used internally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
236
+ # * element_instance - an Element subclass instance
237
+ # * how - symbol - the way we look for the object. Supported values are
238
+ # - :name
239
+ # - :id
240
+ # - :index
241
+ # - :value etc
242
+ # * what - string that we are looking for, ex. the name, or id tag attribute or index of the object we are looking for.
243
+ # * value - used for objects that have one name, but many values. ex. radio lists and checkboxes
244
+ def locate_input_element(element_instance, how, what, value = nil)
245
+ idents = element_instance.class::TAGS
246
+ tags = idents.map { |e| e.tag }
247
+ begin
248
+ case how
249
+ when :id
250
+ case what
251
+ when Regexp
252
+ elements_by_tag_names(tags).find { |elem| elem.getIdAttribute =~ what }
253
+ when String
254
+ @object.getHtmlElementById(what)
255
+ else
256
+ raise ArgumentError, "Argument #{what.inspect} should be a String or Regexp"
257
+ end
258
+ when :name, :value
259
+ elements_by_idents(idents).find do |e|
260
+ matches?(e.getAttribute(how.to_s), what) && (value ? matches?(e.getValueAttribute, value) : true)
261
+ end
262
+ when :caption
263
+ elements_by_idents(idents).find { |e| matches?(e.getValueAttribute, what) }
264
+ when :class
265
+ elements_by_idents(idents).find { |e| matches?(e.getClassAttribute, what) }
266
+ when :text
267
+ elements_by_idents(idents).find { |e| matches?(e.asText, what) }
268
+ when :index
269
+ elements_by_idents(idents)[what.to_i - 1]
270
+ when :xpath
271
+ what = ".#{what}" if what[0] == ?/
272
+ @object.getByXPath(what).to_a.first
273
+ else
274
+ raise MissingWayOfFindingObjectException
275
+ end
276
+ rescue HtmlUnit::ElementNotFoundException
277
+ end
278
+ end
279
+
280
+ def locate_tagged_element(element_instance, how, what)
281
+ tags = element_instance.class::TAGS
282
+ begin
283
+ case how
284
+ when :id
285
+ case what
286
+ when Regexp
287
+ elements_by_tag_names(tags).find { |elem| elem.getIdAttribute =~ what }
288
+ when String
289
+ @object.getHtmlElementById(what)
290
+ else
291
+ raise ArgumentError, "Argument #{what.inspect} should be a String or Regexp"
292
+ end
293
+ when :name, :value, :title
294
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getAttributeValue(how.to_s), what) }
295
+ when :class
296
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getClassAttribute, what)}
297
+ when :text
298
+ elements_by_tag_names(tags).find { |elem| matches?(elem.asText, what) }
299
+ when :index
300
+ elements_by_tag_names(tags)[what.to_i-1]
301
+ when :xpath
302
+ what = ".#{what}" if what[0] == ?/
303
+ @object.getByXPath(what).to_a.first
304
+ when :url
305
+ case element_instance
306
+ when Celerity::Link, Celerity::Map, Celerity::Area
307
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getHrefAttribute, what) }
308
+ end
309
+ when :src
310
+ case element_instance
311
+ when Celerity::Image
312
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getSrcAttribute, what) }
313
+ end
314
+ when :alt
315
+ case element_instance
316
+ when Celerity::Image
317
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getAltAttribute, what) }
318
+ end
319
+ when :action
320
+ case element_instance
321
+ when Celerity::Form
322
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getActionAttribute, what) }
323
+ end
324
+ when :method
325
+ case element_instance
326
+ when Celerity::Form
327
+ elements_by_tag_names(tags).find { |elem| matches?(elem.getMethodAttribute, what) }
328
+ end
329
+ else
330
+ raise MissingWayOfFindingObjectException, "No how #{how.inspect}"
331
+ end
332
+ rescue HtmlUnit::ElementNotFoundException
333
+ end
334
+ end
335
+
336
+ private
337
+
338
+ # this could be optimized when iterating - we don't need to check the class of 'what' for each element
339
+ # perhaps something like this
340
+ # find_matching_element(collection, method = :to_s, what)
341
+ def matches?(string, what)
342
+ Regexp === what ? string.match(what) : string == what.to_s
343
+ end
344
+
345
+ def elements_by_tag_names(tags)
346
+ # HtmlUnit's getHtmlElementsByTagNames won't get elements in the correct order, making :index fail
347
+ tags.map! { |t| t.downcase }
348
+ @object.getAllHtmlChildElements.iterator.to_a.select do |elem|
349
+ tags.include?(elem.getTagName)
350
+ end
351
+ end
352
+
353
+ def elements_by_idents(idents)
354
+ elements = elements_by_tag_names(idents.map { |i| i.tag })
355
+ # Log.debug elements.inspect
356
+ elements.select do |e|
357
+ idents.any? do |ident|
358
+ next unless ident.tag == e.getTagName
359
+ if ident.attributes.empty?
360
+ true
361
+ else
362
+ ident.attributes.any? { |key, value| value.include?(e.getAttributeValue(key.to_s)) }
363
+ end
364
+ end
365
+ end
366
+ end
367
+
368
+ end # Container
369
+ end # Celerity