druid-ts 0.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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