druid-s 1.0.0

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 (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +27 -0
  6. data/ChangeLog +541 -0
  7. data/Gemfile +8 -0
  8. data/README.md +78 -0
  9. data/Rakefile +33 -0
  10. data/cucumber.yml +6 -0
  11. data/druid.gemspec +30 -0
  12. data/features/area.feature +33 -0
  13. data/features/async.feature +16 -0
  14. data/features/audio.feature +61 -0
  15. data/features/bold.feature +20 -0
  16. data/features/button.feature +81 -0
  17. data/features/canvas.feature +34 -0
  18. data/features/checkbox.feature +48 -0
  19. data/features/div.feature +45 -0
  20. data/features/element.feature +281 -0
  21. data/features/file_field.feature +38 -0
  22. data/features/form.feature +37 -0
  23. data/features/frames.feature +76 -0
  24. data/features/generic_elements.feature +29 -0
  25. data/features/heading.feature +160 -0
  26. data/features/hidden_field.feature +39 -0
  27. data/features/html/async.html +31 -0
  28. data/features/html/frame_1.html +18 -0
  29. data/features/html/frame_2.html +16 -0
  30. data/features/html/frame_3.html +14 -0
  31. data/features/html/frames.html +12 -0
  32. data/features/html/hover.html +11 -0
  33. data/features/html/iframes.html +12 -0
  34. data/features/html/images/circle.png +0 -0
  35. data/features/html/images/img_pulpit.jpg +0 -0
  36. data/features/html/modal.html +17 -0
  37. data/features/html/modal_1.html +38 -0
  38. data/features/html/modal_2.html +27 -0
  39. data/features/html/multi_elements.html +145 -0
  40. data/features/html/nested_elements.html +75 -0
  41. data/features/html/nested_frame_1.html +1 -0
  42. data/features/html/nested_frame_2.html +11 -0
  43. data/features/html/nested_frame_3.html +14 -0
  44. data/features/html/nested_frames.html +10 -0
  45. data/features/html/planets.gif +0 -0
  46. data/features/html/static_elements.html +203 -0
  47. data/features/html/success.html +8 -0
  48. data/features/html/sun.gif +0 -0
  49. data/features/html/sun.html +7 -0
  50. data/features/image.feature +47 -0
  51. data/features/italic.feature +20 -0
  52. data/features/javascript.feature +28 -0
  53. data/features/label.feature +43 -0
  54. data/features/link.feature +56 -0
  55. data/features/list_item.feature +37 -0
  56. data/features/modal_dialog.feature +9 -0
  57. data/features/multi_elements.feature +498 -0
  58. data/features/nested_elements.feature +121 -0
  59. data/features/ordered_list.feature +46 -0
  60. data/features/page_level_actions.feature +116 -0
  61. data/features/paragraph.feature +33 -0
  62. data/features/populate_page_with.feature +25 -0
  63. data/features/radio_button.feature +51 -0
  64. data/features/radio_button_group.feature +28 -0
  65. data/features/sample-app/public/04-Death_Becomes_Fur.mp4 +0 -0
  66. data/features/sample-app/public/04-Death_Becomes_Fur.oga +0 -0
  67. data/features/sample-app/public/audio_video.html +19 -0
  68. data/features/sample-app/public/jquery-1.3.2.js +4376 -0
  69. data/features/sample-app/public/jquery.html +28 -0
  70. data/features/sample-app/public/movie.mp4 +0 -0
  71. data/features/sample-app/public/movie.ogg +0 -0
  72. data/features/sample-app/public/prototype-1.6.0.3.js +4320 -0
  73. data/features/sample-app/public/prototype.html +32 -0
  74. data/features/sample-app/sample_app.rb +35 -0
  75. data/features/section.feature +132 -0
  76. data/features/select_list.feature +84 -0
  77. data/features/span.feature +43 -0
  78. data/features/step_definations/area_steps.rb +23 -0
  79. data/features/step_definations/async_steps.rb +80 -0
  80. data/features/step_definations/audio_steps.rb +47 -0
  81. data/features/step_definations/bold_steps.rb +11 -0
  82. data/features/step_definations/button_steps.rb +52 -0
  83. data/features/step_definations/canvas_steps.rb +19 -0
  84. data/features/step_definations/checkbox_steps.rb +39 -0
  85. data/features/step_definations/div_steps.rb +28 -0
  86. data/features/step_definations/element_steps.rb +217 -0
  87. data/features/step_definations/file_field_steps.rb +31 -0
  88. data/features/step_definations/form_steps.rb +23 -0
  89. data/features/step_definations/frame_steps.rb +189 -0
  90. data/features/step_definations/generic_element_steps.rb +31 -0
  91. data/features/step_definations/heading_steps.rb +39 -0
  92. data/features/step_definations/hidden_field_steps.rb +27 -0
  93. data/features/step_definations/image_steps.rb +35 -0
  94. data/features/step_definations/italic_steps.rb +11 -0
  95. data/features/step_definations/javasript_steps.rb +52 -0
  96. data/features/step_definations/label_steps.rb +19 -0
  97. data/features/step_definations/link_steps.rb +42 -0
  98. data/features/step_definations/list_item_steps.rb +24 -0
  99. data/features/step_definations/modal_dialog_steps.rb +38 -0
  100. data/features/step_definations/multi_elements_steps.rb +557 -0
  101. data/features/step_definations/nested_elements_steps.rb +219 -0
  102. data/features/step_definations/ordered_list_steps.rb +49 -0
  103. data/features/step_definations/page_level_actions_steps.rb +172 -0
  104. data/features/step_definations/page_traversal_steps.rb +4 -0
  105. data/features/step_definations/paragraph_steps.rb +19 -0
  106. data/features/step_definations/populate_page_with_steps.rb +3 -0
  107. data/features/step_definations/radio_button_group_steps.rb +32 -0
  108. data/features/step_definations/radio_button_steps.rb +31 -0
  109. data/features/step_definations/section_steps.rb +271 -0
  110. data/features/step_definations/select_list_steps.rb +91 -0
  111. data/features/step_definations/span_steps.rb +23 -0
  112. data/features/step_definations/table_cell_steps.rb +27 -0
  113. data/features/step_definations/table_row_steps.rb +23 -0
  114. data/features/step_definations/table_steps.rb +109 -0
  115. data/features/step_definations/text_area_steps.rb +39 -0
  116. data/features/step_definations/text_field_steps.rb +39 -0
  117. data/features/step_definations/unordered_list_steps.rb +27 -0
  118. data/features/step_definations/video_steps.rb +27 -0
  119. data/features/support/ajax_test_environment.rb +26 -0
  120. data/features/support/audio_video_page.rb +23 -0
  121. data/features/support/env.rb +5 -0
  122. data/features/support/hooks.rb +3 -0
  123. data/features/support/page.rb +372 -0
  124. data/features/support/persistent_browser.rb +58 -0
  125. data/features/support/targets/firefox14_osx.rb +5 -0
  126. data/features/support/targets/firefox14_windows7.rb +5 -0
  127. data/features/support/url_helper.rb +50 -0
  128. data/features/table.feature +127 -0
  129. data/features/table_cell.feature +42 -0
  130. data/features/table_row.feature +30 -0
  131. data/features/text_area.feature +44 -0
  132. data/features/text_field.feature +53 -0
  133. data/features/unordered_list.feature +46 -0
  134. data/features/video.feature +66 -0
  135. data/lib/druid/accessors.rb +1082 -0
  136. data/lib/druid/assist.rb +653 -0
  137. data/lib/druid/element_locators.rb +21 -0
  138. data/lib/druid/elements/area.rb +9 -0
  139. data/lib/druid/elements/audio.rb +9 -0
  140. data/lib/druid/elements/bold.rb +8 -0
  141. data/lib/druid/elements/button.rb +12 -0
  142. data/lib/druid/elements/canvas.rb +9 -0
  143. data/lib/druid/elements/check_box.rb +9 -0
  144. data/lib/druid/elements/div.rb +9 -0
  145. data/lib/druid/elements/element.rb +187 -0
  146. data/lib/druid/elements/file_field.rb +9 -0
  147. data/lib/druid/elements/form.rb +9 -0
  148. data/lib/druid/elements/heading.rb +14 -0
  149. data/lib/druid/elements/hidden_field.rb +9 -0
  150. data/lib/druid/elements/image.rb +9 -0
  151. data/lib/druid/elements/italic.rb +9 -0
  152. data/lib/druid/elements/label.rb +8 -0
  153. data/lib/druid/elements/link.rb +9 -0
  154. data/lib/druid/elements/list_item.rb +9 -0
  155. data/lib/druid/elements/media.rb +11 -0
  156. data/lib/druid/elements/option.rb +9 -0
  157. data/lib/druid/elements/ordered_list.rb +29 -0
  158. data/lib/druid/elements/paragraph.rb +9 -0
  159. data/lib/druid/elements/radio_button.rb +9 -0
  160. data/lib/druid/elements/select_list.rb +30 -0
  161. data/lib/druid/elements/span.rb +9 -0
  162. data/lib/druid/elements/table.rb +92 -0
  163. data/lib/druid/elements/table_cell.rb +11 -0
  164. data/lib/druid/elements/table_row.rb +50 -0
  165. data/lib/druid/elements/text_area.rb +10 -0
  166. data/lib/druid/elements/text_field.rb +11 -0
  167. data/lib/druid/elements/unordered_list.rb +32 -0
  168. data/lib/druid/elements/video.rb +8 -0
  169. data/lib/druid/elements.rb +55 -0
  170. data/lib/druid/javascript/angularjs.rb +12 -0
  171. data/lib/druid/javascript/jquery.rb +12 -0
  172. data/lib/druid/javascript/prototype.rb +12 -0
  173. data/lib/druid/javascript/yui.rb +19 -0
  174. data/lib/druid/javascript_framework_facade.rb +76 -0
  175. data/lib/druid/locator_generator.rb +181 -0
  176. data/lib/druid/nested_elements.rb +56 -0
  177. data/lib/druid/page_factory.rb +115 -0
  178. data/lib/druid/page_populator.rb +104 -0
  179. data/lib/druid/section_collection.rb +17 -0
  180. data/lib/druid/version.rb +3 -0
  181. data/lib/druid.rb +452 -0
  182. data/spec/druid/accessors_spec.rb +1209 -0
  183. data/spec/druid/druid_spec.rb +295 -0
  184. data/spec/druid/element_locators_spec.rb +750 -0
  185. data/spec/druid/elements/bold_spec.rb +12 -0
  186. data/spec/druid/elements/button_spec.rb +23 -0
  187. data/spec/druid/elements/check_box_spec.rb +14 -0
  188. data/spec/druid/elements/div_spec.rb +10 -0
  189. data/spec/druid/elements/element_spec.rb +250 -0
  190. data/spec/druid/elements/file_field_spec.rb +13 -0
  191. data/spec/druid/elements/form_spec.rb +18 -0
  192. data/spec/druid/elements/heading_spec.rb +30 -0
  193. data/spec/druid/elements/hidden_field_spec.rb +10 -0
  194. data/spec/druid/elements/image_spec.rb +23 -0
  195. data/spec/druid/elements/itatic_spec.rb +11 -0
  196. data/spec/druid/elements/label_spec.rb +10 -0
  197. data/spec/druid/elements/link_spec.rb +10 -0
  198. data/spec/druid/elements/list_item_spec.rb +10 -0
  199. data/spec/druid/elements/media_spec.rb +12 -0
  200. data/spec/druid/elements/option_spec.rb +21 -0
  201. data/spec/druid/elements/ordered_list_spec.rb +38 -0
  202. data/spec/druid/elements/page_factory_spec.rb +40 -0
  203. data/spec/druid/elements/paragraph_spec.rb +12 -0
  204. data/spec/druid/elements/radio_button_spec.rb +14 -0
  205. data/spec/druid/elements/select_list_spec.rb +51 -0
  206. data/spec/druid/elements/span_spec.rb +10 -0
  207. data/spec/druid/elements/table_cell_spec.rb +14 -0
  208. data/spec/druid/elements/table_row_spec.rb +34 -0
  209. data/spec/druid/elements/table_spec.rb +47 -0
  210. data/spec/druid/elements/text_area_spec.rb +13 -0
  211. data/spec/druid/elements/text_field_spec.rb +22 -0
  212. data/spec/druid/elements/unordered_list_spec.rb +39 -0
  213. data/spec/druid/javascript_framework_facade_spec.rb +59 -0
  214. data/spec/druid/nested_element_spec.rb +128 -0
  215. data/spec/druid/page_factory_spec.rb +235 -0
  216. data/spec/druid/page_populator_spec.rb +173 -0
  217. data/spec/druid/page_section_spec.rb +70 -0
  218. data/spec/spec_helper.rb +9 -0
  219. metadata +517 -0
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Canvas < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:canvas] = Druid::Elements::Canvas
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class CheckBox < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:checkbox] = Druid::Elements::CheckBox
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Div < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:div] = Druid::Elements::Div
8
+ end
9
+ end
@@ -0,0 +1,187 @@
1
+ require 'druid/nested_elements'
2
+ require 'druid/assist'
3
+ module Druid
4
+ module Elements
5
+ #
6
+ # Contains functionality that is common across all elements
7
+ #
8
+ class Element
9
+ include Druid::NestedElements
10
+ include Druid::Assist
11
+
12
+ attr_accessor :element
13
+ attr_accessor :driver
14
+
15
+ def initialize(element)
16
+ @element = element
17
+ @driver = @element
18
+ end
19
+
20
+ #
21
+ # return true if the element is not enabled
22
+ def disabled?
23
+ not enabled?
24
+ end
25
+
26
+ #
27
+ # return true if the element exists and is visible
28
+ #
29
+ def present?
30
+ element.present?
31
+ end
32
+
33
+ #
34
+ # compare this element to another to determine if they are equal
35
+ # @return [Boolean]
36
+ #
37
+ def ==(other)
38
+ other.is_a? self.class and element == other.element
39
+ end
40
+
41
+ def check_visible(timeout=Druid.default_element_wait)
42
+ timed_loop(timeout) do |element|
43
+ element.present?
44
+ end
45
+ # wait_until(timeout: timeout, message: "Element not visible in #{timeout} seconds", &:present?)
46
+ end
47
+ # alias_method :when_present, :check_visible
48
+ # alias_method :when_visible, :check_visible
49
+
50
+ def check_exist(timeout=Druid.default_element_wait)
51
+ timed_loop(timeout) do |element|
52
+ element.exists?
53
+ end
54
+ # wait_until(timeout: timeout, &:exist?)
55
+ end
56
+
57
+ #
58
+ # find the parent element
59
+ #
60
+ def parent(opt = {})
61
+ parent = element.parent(opt)
62
+ druid_wrapper(parent)
63
+ end
64
+
65
+ #
66
+ # Return the element that exists at the same level of the DOM
67
+ # immediately prior to this element
68
+ #
69
+ def preceding_sibling(opt = {})
70
+ sibling = element.preceding_sibling(opt)
71
+ druid_wrapper(sibling)
72
+ end
73
+
74
+ #
75
+ # Return the element that exists at the same level of the DOM
76
+ # immediately after this element
77
+ #
78
+ def following_sibling(opt={})
79
+ sibling = element.following_sibling(opt)
80
+ druid_wrapper(sibling)
81
+ end
82
+
83
+ #
84
+ # Return all elements that are direct children of this element's parent
85
+ #
86
+ def siblings(opt={})
87
+ siblings = element.siblings(opt)
88
+ siblings.collect {|sibling| druid_wrapper(sibling)}
89
+ end
90
+
91
+ #
92
+ # Return all elements that are children of this element
93
+ #
94
+ def children(opt={})
95
+ children = element.children(opt)
96
+ children.collect {|child| druid_wrapper(child)}
97
+ end
98
+
99
+ #
100
+ # Return all elements that exist at the same level of the DOM
101
+ # immediately prior to this element
102
+ #
103
+ def preceding_siblings(opt={})
104
+ siblings = element.preceding_siblings(opt)
105
+ siblings.collect {|sibling| druid_wrapper(sibling)}
106
+ end
107
+
108
+ #
109
+ # Return all elements that exist at the same level of the DOM
110
+ # immediately after this element
111
+ #
112
+ def following_siblings(opt={})
113
+ siblings = element.following_siblings(opt)
114
+ siblings.collect {|sibling| druid_wrapper(sibling)}
115
+ end
116
+
117
+ #
118
+ # Wait until the element is present
119
+ #
120
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
121
+ #
122
+ def when_present(timeout=Druid.default_element_wait)
123
+ element.wait_until(timeout: timeout, message: "Element not present in #{timeout} seconds", &:present?)
124
+ self
125
+ end
126
+ alias_method :when_visible, :when_present
127
+
128
+ #
129
+ # Waits until the element is not present
130
+ #
131
+ # @param [Integer] (defaults to: 5) seconds to wait before
132
+ # timing out
133
+ #
134
+ def when_not_present(timeout=Druid.default_element_wait)
135
+ element.wait_while(timeout: timeout, message: "Element still present in #{timeout} seconds", &:present?)
136
+ end
137
+ alias_method :when_not_visible, :when_not_present
138
+
139
+ #
140
+ # Waits until the block returns true
141
+ #
142
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
143
+ # @param [String] the message to display if the event timeouts
144
+ # @param the block to execute when the event occurs
145
+ #
146
+ def wait_until(timeout=Druid.default_element_wait, message=nil, &block)
147
+ element.wait_until(timeout: timeout, message: message, &block)
148
+ end
149
+
150
+ def name
151
+ element.attribute(:name)
152
+ end
153
+
154
+ # @private
155
+ # delegate calls to driver element
156
+ def method_missing(*args, &block)
157
+ m = args.shift
158
+ element.send m, *args, &block
159
+ end
160
+
161
+ def respond_to_missing?(m,*args)
162
+ element.respond_to?(m) || super
163
+ end
164
+
165
+ protected
166
+
167
+ def druid_wrapper(object)
168
+ type = element.type if object.tag_name.to_sym == :input
169
+ cls = Druid::Elements.element_class_for(object.tag_name, type)
170
+ cls.new(object.to_subtype)
171
+ end
172
+
173
+ private
174
+
175
+ def timed_loop(timeout)
176
+ end_time = ::Time.now + timeout
177
+ until ::Time.now > end_time
178
+ result = yield(self)
179
+ return result if result
180
+ sleep 0.5
181
+ end
182
+ false
183
+ end
184
+
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class FileField < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:file] = Druid::Elements::FileField
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Form < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:form] = Druid::Elements::Form
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Druid
2
+ module Elements
3
+ class Heading < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:h1] = Druid::Elements::Heading
8
+ Druid::Elements.tag_to_class[:h2] = Druid::Elements::Heading
9
+ Druid::Elements.tag_to_class[:h3] = Druid::Elements::Heading
10
+ Druid::Elements.tag_to_class[:h4] = Druid::Elements::Heading
11
+ Druid::Elements.tag_to_class[:h5] = Druid::Elements::Heading
12
+ Druid::Elements.tag_to_class[:h6] = Druid::Elements::Heading
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class HiddenField < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:hidden] = Druid::Elements::HiddenField
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Image < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:img] = Druid::Elements::Image
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Italic < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:i] = Druid::Elements::Italic
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Druid
2
+ module Elements
3
+ class Label < Element
4
+
5
+ Druid::Elements.tag_to_class[:label] = Druid::Elements::Label
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Link < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:a] = Druid::Elements::Link
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class ListItem < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:li] = Druid::Elements::ListItem
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class Media < Element
4
+
5
+ def has_controls?
6
+ attribute(:controls)
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Option < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:option] = Druid::Elements::Option
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Druid
2
+ module Elements
3
+ class OrderedList < Element
4
+ attr_accessor :li_element
5
+
6
+ def [](idx)
7
+ list_items[idx]
8
+ end
9
+
10
+ def items
11
+ list_items.size
12
+ end
13
+
14
+ def each(&block)
15
+ list_items.each(&block)
16
+ end
17
+
18
+ #
19
+ # Return Array of ListItem objects that are children of the OrderedList
20
+ #
21
+ def list_items
22
+ @list_items ||= children(tag_name: 'li')
23
+ end
24
+
25
+ end
26
+
27
+ Druid::Elements.tag_to_class[:ol] = Druid::Elements::OrderedList
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Paragraph < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:p] = Druid::Elements::Paragraph
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class RadioButton < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:radio] = Druid::Elements::RadioButton
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ module Druid
2
+ module Elements
3
+ class SelectList < Element
4
+
5
+ def [](idx)
6
+ options[idx]
7
+ end
8
+
9
+ def options
10
+ element.options.map { |e| Druid::Elements::Option.new(e)}
11
+ end
12
+
13
+ #
14
+ # @return [Array<String>] An array of strings representing the text of the currently selected options.
15
+ #
16
+ def selected_options
17
+ element.selected_options.map(&:text).compact
18
+ end
19
+
20
+ #
21
+ # @return [Array<String>] An array of strings representing the value of the currently selected options.
22
+ def selected_values
23
+ element.selected_options.map(&:value).compact
24
+ end
25
+
26
+ end
27
+
28
+ Druid::Elements.tag_to_class[:select] = Druid::Elements::SelectList
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module Druid
2
+ module Elements
3
+ class Span < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:span] = Druid::Elements::Span
8
+ end
9
+ end
@@ -0,0 +1,92 @@
1
+ module Druid
2
+ module Elements
3
+ class Table < Element
4
+ #
5
+ # Return the Druid::Elements::Table for the index provided. Index
6
+ # is zero based. If the index provided is a String then it
7
+ # will be matched with the text from any column. The text can be
8
+ # a substring of the full column text.
9
+ #
10
+ # @return [Druid::Elements::TableRow]
11
+ #
12
+ def [](what)
13
+ idx = find_index(what)
14
+ idx && row_items[idx]
15
+ end
16
+
17
+ #
18
+ # Returns the number of rows in the table.
19
+ #
20
+ def rows
21
+ row_items.size
22
+ end
23
+
24
+ #
25
+ # iterator that yields with a Druid::Elements::TableRow
26
+ #
27
+ # @return [Druid::Elements::TableRow]
28
+ #
29
+ def each(&block)
30
+ row_items.each(&block)
31
+ end
32
+
33
+ #
34
+ # return the first row
35
+ #
36
+ # @return Druid::Elements::TableRow
37
+ #
38
+ def first_row
39
+ self[0]
40
+ end
41
+
42
+ #
43
+ # return the last row
44
+ #
45
+ # @return Druid::Elements::TableRow
46
+ #
47
+ def last_row
48
+ self[-1]
49
+ end
50
+
51
+ #
52
+ # Returns the Array of values(String) in a column for the index provided. Index
53
+ # is zero based. If the index provided is a String then it
54
+ # will be matched with the text from the header. The text can be a substring of the full header text
55
+ #
56
+ def column_values(what)
57
+ idx = find_index_of_header(what)
58
+ idx && row_items.drop(1).collect{ |row| row.cell(index: idx).text }
59
+ end
60
+
61
+ private
62
+
63
+ def row_items
64
+ meth = stragegy == :descendants ? :trs : :rows
65
+ @row_items ||= element.send(meth).map do |obj|
66
+ Druid::Elements::TableRow.new(obj)
67
+ end
68
+ end
69
+
70
+ def stragegy
71
+ :children
72
+ end
73
+
74
+ def find_index_of_header(what)
75
+ return what if what.is_a? Integer
76
+ row_items[0].cells.find_index do |cell|
77
+ cell.text.include? Regexp.escape(what)
78
+ end
79
+ end
80
+
81
+ def find_index(what)
82
+ return what if what.is_a? Integer
83
+ row_items.find_index do |row|
84
+ row.cell(text: /#{Regexp.escape(what)}/).exist?
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ Druid::Elements.tag_to_class[:table] = Druid::Elements::Table
91
+ end
92
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class TableCell < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:td] = Druid::Elements::TableCell
8
+ Druid::Elements.tag_to_class[:th] = Druid::Elements::TableCell
9
+
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ require 'watir/elements/html_elements'
2
+ module Druid
3
+ module Elements
4
+ class TableRow < Element
5
+
6
+ #
7
+ # Return the Druid::Elements::TableCell for the index provided. Index
8
+ # is zero based. If the index provided is a String then it
9
+ # will be matched with the text from the columns in the first row.
10
+ #
11
+ def [](what)
12
+ idx = find_index(what)
13
+ idx && cell_items[idx]
14
+ end
15
+
16
+ #
17
+ # Returns the number of colums in the table
18
+ #
19
+ def columns
20
+ cell_items.size
21
+ end
22
+
23
+ #
24
+ # iterator that yields with a Druid::Elements::TableCell
25
+ #
26
+ def each(&block)
27
+ cell_items.each(&block)
28
+ end
29
+
30
+ private
31
+
32
+ def cell_items
33
+ @cell_items ||= element.cells.map do |obj|
34
+ Druid::Elements::TableCell.new(obj)
35
+ end
36
+ end
37
+
38
+ def find_index(what)
39
+ return what if what.is_a? Integer
40
+ parent(tag_name: 'table').headers.find_index do |header|
41
+ header.text.include? what
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ Druid::Elements.tag_to_class[:tr] = Druid::Elements::TableRow
48
+
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ module Druid
2
+ module Elements
3
+ class TextArea < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.tag_to_class[:textarea] = Druid::Elements::TextArea
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module Druid
2
+ module Elements
3
+ class TextField < Element
4
+
5
+ end
6
+
7
+ Druid::Elements.type_to_class[:text] = Druid::Elements::TextField
8
+ Druid::Elements.type_to_class[:password] = Druid::Elements::TextField
9
+
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Druid
2
+ module Elements
3
+ class UnOrderedList < Element
4
+
5
+ #
6
+ # @return [Druid::Elements::ListItem]
7
+ #
8
+ def [](idx)
9
+ list_items[idx]
10
+ end
11
+
12
+ def items
13
+ list_items.size
14
+ end
15
+
16
+ def each(&block)
17
+ list_items.each(&block)
18
+ end
19
+
20
+ #
21
+ # Return Array of ListItem objects that are children of the UnorderedList
22
+ #
23
+ def list_items
24
+ @list_items ||= children(tag_name: 'li')
25
+ end
26
+
27
+ end
28
+
29
+ Druid::Elements.tag_to_class[:ul] = Druid::Elements::UnOrderedList
30
+
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ module Druid
2
+ module Elements
3
+ class Video < Media
4
+
5
+ end
6
+ Druid::Elements.type_to_class[:video] = Druid::Elements::Video
7
+ end
8
+ end