druid-ts 0.0.1 → 1.1.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 (145) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +1 -2
  6. data/ChangeLog +218 -0
  7. data/Gemfile +2 -1
  8. data/README.md +64 -7
  9. data/Rakefile +1 -1
  10. data/druid.gemspec +25 -0
  11. data/features/async.feature +18 -0
  12. data/features/button.feature +42 -1
  13. data/features/checkbox.feature +7 -1
  14. data/features/div.feature +6 -0
  15. data/features/element.feature +100 -0
  16. data/features/file_field.feature +35 -0
  17. data/features/form.feature +12 -6
  18. data/features/frames.feature +57 -0
  19. data/features/heading.feature +164 -0
  20. data/features/hidden_field.feature +6 -0
  21. data/features/html/async.html +18 -0
  22. data/features/html/frame_1.html +18 -0
  23. data/features/html/frame_2.html +16 -0
  24. data/features/html/frame_3.html +14 -0
  25. data/features/html/frames.html +12 -0
  26. data/features/html/iframes.html +12 -0
  27. data/features/html/modal.html +17 -0
  28. data/features/html/modal_1.html +38 -0
  29. data/features/html/modal_2.html +27 -0
  30. data/features/html/nested_elements.html +52 -0
  31. data/features/html/nested_frame_1.html +1 -0
  32. data/features/html/nested_frame_2.html +11 -0
  33. data/features/html/nested_frame_3.html +14 -0
  34. data/features/html/nested_frames.html +10 -0
  35. data/features/html/static_elements.html +29 -23
  36. data/features/image.feature +8 -0
  37. data/features/link.feature +5 -0
  38. data/features/list_item.feature +5 -0
  39. data/features/modal_dialog.feature +9 -0
  40. data/features/nested_elements.feature +105 -0
  41. data/features/ordered_list.feature +6 -0
  42. data/features/page_level_actions.feature +48 -0
  43. data/features/paragraph.feature +33 -0
  44. data/features/radio_button.feature +6 -0
  45. data/features/select_list.feature +6 -1
  46. data/features/span.feature +6 -1
  47. data/features/step_definations/async_steps.rb +63 -0
  48. data/features/step_definations/button_steps.rb +25 -1
  49. data/features/step_definations/checkbox_steps.rb +5 -1
  50. data/features/step_definations/div_steps.rb +6 -1
  51. data/features/step_definations/element_steps.rb +55 -1
  52. data/features/step_definations/file_field_steps.rb +27 -0
  53. data/features/step_definations/form_steps.rb +8 -0
  54. data/features/step_definations/frame_steps.rb +112 -0
  55. data/features/step_definations/heading_steps.rb +39 -0
  56. data/features/step_definations/hidden_field_steps.rb +7 -3
  57. data/features/step_definations/image_steps.rb +7 -3
  58. data/features/step_definations/link_steps.rb +8 -3
  59. data/features/step_definations/list_item_steps.rb +9 -1
  60. data/features/step_definations/modal_dialog_steps.rb +38 -0
  61. data/features/step_definations/nested_elements_steps.rb +196 -0
  62. data/features/step_definations/ordered_list_steps.rb +11 -3
  63. data/features/step_definations/page_level_actions_steps.rb +72 -0
  64. data/features/step_definations/paragraph_steps.rb +15 -0
  65. data/features/step_definations/radio_button_steps.rb +5 -1
  66. data/features/step_definations/select_list_steps.rb +10 -2
  67. data/features/step_definations/span_steps.rb +5 -1
  68. data/features/step_definations/table_cell_steps.rb +5 -1
  69. data/features/step_definations/table_steps.rb +17 -3
  70. data/features/step_definations/text_area_steps.rb +18 -2
  71. data/features/step_definations/text_field_steps.rb +9 -1
  72. data/features/step_definations/unordered_list_steps.rb +11 -3
  73. data/features/support/env.rb +0 -15
  74. data/features/support/hooks.rb +7 -0
  75. data/features/support/page.rb +98 -1
  76. data/features/support/persistent_browser.rb +15 -0
  77. data/features/support/url_helper.rb +24 -1
  78. data/features/table.feature +7 -0
  79. data/features/table_cell.feature +6 -0
  80. data/features/text_area.feature +11 -0
  81. data/features/text_field.feature +6 -1
  82. data/features/unordered_list.feature +6 -0
  83. data/lib/druid.rb +251 -3
  84. data/lib/druid/accessors.rb +446 -158
  85. data/lib/druid/assist.rb +394 -0
  86. data/lib/druid/core_ext/string.rb +5 -0
  87. data/lib/druid/element_locators.rb +405 -0
  88. data/lib/druid/elements.rb +28 -0
  89. data/lib/druid/elements/button.rb +6 -1
  90. data/lib/druid/elements/check_box.rb +26 -0
  91. data/lib/druid/elements/div.rb +3 -1
  92. data/lib/druid/elements/element.rb +170 -5
  93. data/lib/druid/elements/file_field.rb +18 -0
  94. data/lib/druid/elements/form.rb +11 -0
  95. data/lib/druid/elements/heading.rb +14 -0
  96. data/lib/druid/elements/hidden_field.rb +12 -2
  97. data/lib/druid/elements/image.rb +13 -0
  98. data/lib/druid/elements/link.rb +2 -0
  99. data/lib/druid/elements/list_item.rb +3 -1
  100. data/lib/druid/elements/option.rb +9 -0
  101. data/lib/druid/elements/ordered_list.rb +4 -5
  102. data/lib/druid/elements/paragraph.rb +9 -0
  103. data/lib/druid/elements/radio_button.rb +25 -0
  104. data/lib/druid/elements/select_list.rb +10 -1
  105. data/lib/druid/elements/span.rb +3 -1
  106. data/lib/druid/elements/table.rb +20 -1
  107. data/lib/druid/elements/table_cell.rb +7 -0
  108. data/lib/druid/elements/table_row.rb +5 -1
  109. data/lib/druid/elements/text_area.rb +15 -1
  110. data/lib/druid/elements/text_field.rb +11 -1
  111. data/lib/druid/elements/unordered_list.rb +5 -5
  112. data/lib/druid/nested_elements.rb +103 -0
  113. data/lib/druid/page_factory.rb +4 -4
  114. data/lib/druid/page_populator.rb +71 -0
  115. data/spec/druid/accessors_spec.rb +789 -0
  116. data/spec/druid/druid_spec.rb +130 -7
  117. data/spec/druid/element_locators_spec.rb +160 -0
  118. data/spec/druid/elements/button_spec.rb +31 -0
  119. data/spec/druid/elements/check_box_spec.rb +38 -0
  120. data/spec/druid/elements/div_spec.rb +19 -0
  121. data/spec/druid/elements/element_spec.rb +150 -0
  122. data/spec/druid/elements/file_field_spec.rb +27 -0
  123. data/spec/druid/elements/form_spec.rb +27 -0
  124. data/spec/druid/elements/heading_spec.rb +39 -0
  125. data/spec/druid/elements/hidden_field_spec.rb +24 -0
  126. data/spec/druid/elements/image_spec.rb +32 -0
  127. data/spec/druid/elements/link_spec.rb +26 -0
  128. data/spec/druid/elements/list_item_spec.rb +19 -0
  129. data/spec/druid/elements/option_spec.rb +10 -0
  130. data/spec/druid/elements/ordered_list_spec.rb +42 -0
  131. data/spec/druid/elements/page_factory_spec.rb +40 -0
  132. data/spec/druid/elements/paragraph_spec.rb +21 -0
  133. data/spec/druid/elements/radio_button_spec.rb +38 -0
  134. data/spec/druid/elements/select_list_spec.rb +37 -0
  135. data/spec/druid/elements/span_spec.rb +19 -0
  136. data/spec/druid/elements/table_cell_spec.rb +23 -0
  137. data/spec/druid/elements/table_row_spec.rb +41 -0
  138. data/spec/druid/elements/table_spec.rb +52 -0
  139. data/spec/druid/elements/text_area_spec.rb +31 -0
  140. data/spec/druid/elements/text_field_spec.rb +31 -0
  141. data/spec/druid/elements/unordered_list_spec.rb +42 -0
  142. data/spec/druid/nested_element_spec.rb +128 -0
  143. data/spec/druid/page_populator_spec.rb +92 -0
  144. data/spec/spec_helper.rb +2 -1
  145. metadata +147 -27
@@ -1,3 +1,27 @@
1
+ module Druid
2
+ module Elements
3
+ class << self
4
+
5
+ def type_to_class
6
+ @type_to_class ||= {}
7
+ end
8
+
9
+ # method to return the collection of tag_name class mappings
10
+ def tag_to_class
11
+ @tag_to_class ||= {}
12
+ end
13
+
14
+ #
15
+ # method to return the element for a tag_name
16
+ #
17
+ def element_class_for(tag_name, type=nil)
18
+ return type_to_class[type] if type
19
+ tag_to_class[tag_name.to_sym] || Druid::Elements::Element
20
+ end
21
+ end
22
+ end
23
+ end
24
+
1
25
  require 'druid/elements/element.rb'
2
26
  require 'druid/elements/ordered_list.rb'
3
27
  require 'druid/elements/unordered_list.rb'
@@ -17,3 +41,7 @@ require 'druid/elements/hidden_field.rb'
17
41
  require 'druid/elements/list_item.rb'
18
42
  require 'druid/elements/text_area.rb'
19
43
  require 'druid/elements/form.rb'
44
+ require 'druid/elements/option.rb'
45
+ require 'druid/elements/heading.rb'
46
+ require 'druid/elements/paragraph.rb'
47
+ require 'druid/elements/file_field.rb'
@@ -3,9 +3,14 @@ module Druid
3
3
  class Button < Element
4
4
 
5
5
  def self.finders
6
- super + [:text]
6
+ super + [:value, :text, :src, :alt]
7
7
  end
8
8
 
9
9
  end
10
+
11
+ Druid::Elements.type_to_class[:submit] = Druid::Elements::Button
12
+ Druid::Elements.type_to_class[:image] = Druid::Elements::Button
13
+ Druid::Elements.type_to_class[:button] = Druid::Elements::Button
14
+ Druid::Elements.type_to_class[:reset] = Druid::Elements::Button
10
15
  end
11
16
  end
@@ -2,6 +2,32 @@ module Druid
2
2
  module Elements
3
3
  class CheckBox < Element
4
4
 
5
+ def self.finders
6
+ super + [:value]
7
+ end
8
+
9
+ #
10
+ # Check the checkbox
11
+ #
12
+ def check
13
+ element.set
14
+ end
15
+
16
+ #
17
+ # Uncheck the CheckBox
18
+ #
19
+ def uncheck
20
+ element.clear
21
+ end
22
+
23
+ #
24
+ # Return true if checkbox is checked
25
+ #
26
+ def checked?
27
+ element.set?
28
+ end
5
29
  end
30
+
31
+ Druid::Elements.type_to_class[:checkbox] = Druid::Elements::CheckBox
6
32
  end
7
33
  end
@@ -3,8 +3,10 @@ module Druid
3
3
  class Div < Element
4
4
 
5
5
  def self.finders
6
- [:class, :id, :index, :xpath]
6
+ [:class, :id, :text, :index, :xpath]
7
7
  end
8
8
  end
9
+
10
+ Druid::Elements.tag_to_class[:div] = Druid::Elements::Div
9
11
  end
10
12
  end
@@ -1,18 +1,23 @@
1
+ require 'druid/nested_elements'
2
+ require 'druid/assist'
1
3
  module Druid
2
4
  module Elements
3
5
  #
4
6
  # Contains functionality that is common across all elements
5
7
  #
6
8
  class Element
9
+ include Druid::NestedElements
10
+ include Druid::Assist
11
+
7
12
  attr_accessor :element
13
+ attr_accessor :driver
8
14
 
9
15
  def initialize(element)
10
16
  @element = element
17
+ @driver = @element
11
18
  end
12
19
 
13
- # def self.identifier_for identifier
14
- # identifier_for_element identifier, finders, mapping
15
- # end
20
+ # @private
16
21
  def self.identifier_for identifier
17
22
  if have_to_build_xpath(identifier)
18
23
  how = :xpath
@@ -30,7 +35,7 @@ module Druid
30
35
  end
31
36
 
32
37
  def self.have_to_build_xpath(identifier)
33
- ['table', 'span', 'div', 'td', 'li', 'ol', 'ul'].include? identifier[:tag_name] and identifier[:name]
38
+ ['table', 'span', 'div', 'td', 'li', 'ol', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].include? identifier[:tag_name] and identifier[:name]
34
39
  end
35
40
 
36
41
  def self.build_xpath_for identifier
@@ -97,6 +102,11 @@ module Druid
97
102
  {}
98
103
  end
99
104
 
105
+ #
106
+ # Get the text for the element
107
+ #
108
+ # @return [String]
109
+ #
100
110
  def text
101
111
  element.text
102
112
  end
@@ -105,25 +115,180 @@ module Druid
105
115
  element.exist?
106
116
  end
107
117
 
118
+ def enabled?
119
+ element.enabled?
120
+ end
121
+
108
122
  def visible?
109
123
  element.visible?
110
124
  end
111
125
 
126
+ #
127
+ # Get the value of this element
128
+ #
129
+ # @return [String]
130
+ #
112
131
  def value
113
132
  element.value
114
133
  end
115
134
 
135
+ #
136
+ # compare this element to another to determine if they are equal
137
+ # @return [Boolean]
138
+ #
139
+ def ==(other)
140
+ element == other.element
141
+ end
142
+
143
+ #
144
+ # Get the tag name of this element
145
+ #
146
+ # @return [String]
147
+ #
116
148
  def tag_name
117
149
  element.tag_name
118
150
  end
119
151
 
120
- def attribute_value(attribute_name)
152
+ #
153
+ # Get the value of the given attribute of the element
154
+ # @param [String]
155
+ # @return [String, nil]
156
+ #
157
+ def attribute(attribute_name)
121
158
  element.attribute_value attribute_name
122
159
  end
123
160
 
161
+ #
162
+ # Click this element
163
+ #
124
164
  def click
125
165
  element.click
126
166
  end
167
+
168
+ #
169
+ # get the value of the given CSS property
170
+ #
171
+ def style(property)
172
+ element.style property
173
+ end
174
+
175
+ def inspect
176
+ element.inspect
177
+ end
178
+
179
+ #
180
+ # Send keystrokes to this element
181
+ #
182
+ # @param [String, Symbol, Array]
183
+ #
184
+ # Examples:
185
+ #
186
+ # element.send_keys "foo" #=> value: 'foo'
187
+ # element.send_keys "tet", :arrow_left, "s" #=> value: 'test'
188
+ # element.send_keys [:control, 'a'], :space #=> value: ' '
189
+ #
190
+ def send_keys(*args)
191
+ element.send_keys(*args)
192
+ end
193
+
194
+ #
195
+ # clear the contents of the element
196
+ #
197
+ def clear
198
+ element.clear
199
+ end
200
+
201
+ #
202
+ # double click this element
203
+ #
204
+ def double_click
205
+ element.double_click
206
+ end
207
+
208
+ #
209
+ # right click this element
210
+ #
211
+ def right_click
212
+ element.right_click
213
+ end
214
+
215
+ #
216
+ # Fire the provided event on the current element
217
+ #
218
+ def fire_event(event_name)
219
+ element.fire_event(event_name)
220
+ end
221
+
222
+ def focus
223
+ element.focus
224
+ end
225
+
226
+ #
227
+ # Returns parent element of current element.
228
+ def parent
229
+ parent = element.parent
230
+ type = element.type if parent.tag_name.to_sym == :input
231
+ cls = Druid::Elements.element_class_for(parent.tag_name, type)
232
+ cls.new(parent)
233
+ end
234
+
235
+ #
236
+ # Waits until the element is present
237
+ #
238
+ # @param [Integer] (default to:5) seconds to wait before timing out
239
+ #
240
+ def when_present(timeout=5)
241
+ element.wait_until_present(timeout)
242
+ self
243
+ end
244
+
245
+ #
246
+ # Waits until the element is visible
247
+ #
248
+ # @param [Interger] (default to:5) seconds to wait before timing out
249
+ #
250
+ def when_visible(timeout=5)
251
+ Watir::Wait.until(timeout, "Element was not visible in #{timeout} seconds") do
252
+ visible?
253
+ end
254
+ self
255
+ end
256
+
257
+ #
258
+ # Waits until the element is not visible
259
+ #
260
+ # @param [Integer] (default to:5) seconds to wait before timing out
261
+ #
262
+ def when_not_visible(timeout=5)
263
+ Watir::Wait.while(timeout, "Element still visible after #{timeout} seconds") do
264
+ visible?
265
+ end
266
+ self
267
+ end
268
+
269
+ #
270
+ # Waits until the block returns true
271
+ #
272
+ # @param [Integer] (default to:5) seconds to wait before timing out
273
+ #
274
+ def wait_until(timeout=5, message=nil, &block)
275
+ Watir::Wait.until(timeout, message, &block)
276
+ end
277
+
278
+ # @private
279
+ # delegate calls to driver element
280
+ def method_missing(m, *args, &block)
281
+ puts "*** DEPRECATION WARNING"
282
+ puts "*** You are calling a method named #{m}."
283
+ puts "*** This method does not exist in druid so it is being passed to the driver."
284
+ puts "*** This feature will be removed in the near future."
285
+ puts "*** Please change your code to call the correct druid method."
286
+ puts "*** If you are using functionality that does not exist in druid please request it be added."
287
+ unless element.respond_to?(m)
288
+ raise NoMethodError, "undefined method `#{m}` for #{element.inspect}:#{element.class}"
289
+ end
290
+ element.__send__(m, *args, &block)
291
+ end
127
292
  end
128
293
  end
129
294
  end
@@ -0,0 +1,18 @@
1
+ module Druid
2
+ module Elements
3
+ class FileField < Element
4
+ def self.finders
5
+ super + [:title]
6
+ end
7
+
8
+ #
9
+ # Set the value of the FileField
10
+ #
11
+ def value=(new_value)
12
+ element.set(new_value)
13
+ end
14
+ end
15
+
16
+ Druid::Elements.type_to_class[:file] = Druid::Elements::FileField
17
+ end
18
+ end
@@ -2,6 +2,17 @@ module Druid
2
2
  module Elements
3
3
  class Form < Element
4
4
 
5
+ def self.finders
6
+ super + [:action]
7
+ end
8
+ #
9
+ # Submit the form
10
+ #
11
+ def submit
12
+ element.submit
13
+ end
5
14
  end
15
+
16
+ Druid::Elements.tag_to_class[:form] = Druid::Elements::Form
6
17
  end
7
18
  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
@@ -1,11 +1,21 @@
1
1
  module Druid
2
2
  module Elements
3
3
  class HiddenField < Element
4
-
4
+
5
+ def click
6
+ raise "click is not available on hidden field element with watir"
7
+ end
8
+
5
9
  def self.finders
6
- super + [:tag_name, :text, :css]
10
+ super + [:tag_name, :text, :value]
11
+ end
12
+
13
+ def self.mapping
14
+ super.merge({:css => :tag_name})
7
15
  end
8
16
 
9
17
  end
18
+
19
+ Druid::Elements.type_to_class[:hidden] = Druid::Elements::HiddenField
10
20
  end
11
21
  end
@@ -2,6 +2,19 @@ module Druid
2
2
  module Elements
3
3
  class Image < Element
4
4
 
5
+ def self.finders
6
+ super + [:alt, :src]
7
+ end
8
+
9
+ def width
10
+ element.width
11
+ end
12
+
13
+ def height
14
+ element.height
15
+ end
5
16
  end
17
+
18
+ Druid::Elements.tag_to_class[:img] = Druid::Elements::Image
6
19
  end
7
20
  end
@@ -12,5 +12,7 @@ module Druid
12
12
  super.merge({:link => :text, :link_text => :text})
13
13
  end
14
14
  end
15
+
16
+ Druid::Elements.tag_to_class[:a] = Druid::Elements::Link
15
17
  end
16
18
  end
@@ -1,7 +1,9 @@
1
1
  module Druid
2
2
  module Elements
3
3
  class ListItem < Element
4
-
4
+
5
5
  end
6
+
7
+ Druid::Elements.tag_to_class[:li] = Druid::Elements::ListItem
6
8
  end
7
9
  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