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,55 @@
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.to_sym] if type
19
+ tag_to_class[tag_name.to_sym] || Druid::Elements::Element
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'druid/elements/element'
26
+ require 'druid/elements/ordered_list'
27
+ require 'druid/elements/unordered_list'
28
+ require 'druid/elements/table'
29
+ require 'druid/elements/table_row'
30
+ require 'druid/elements/select_list'
31
+ require 'druid/elements/link'
32
+ require 'druid/elements/button'
33
+ require 'druid/elements/check_box'
34
+ require 'druid/elements/radio_button'
35
+ require 'druid/elements/text_field'
36
+ require 'druid/elements/div'
37
+ require 'druid/elements/table_cell'
38
+ require 'druid/elements/image'
39
+ require 'druid/elements/span'
40
+ require 'druid/elements/hidden_field'
41
+ require 'druid/elements/list_item'
42
+ require 'druid/elements/text_area'
43
+ require 'druid/elements/form'
44
+ require 'druid/elements/option'
45
+ require 'druid/elements/heading'
46
+ require 'druid/elements/paragraph'
47
+ require 'druid/elements/file_field'
48
+ require 'druid/elements/label'
49
+ require 'druid/elements/area'
50
+ require 'druid/elements/canvas'
51
+ require 'druid/elements/media'
52
+ require 'druid/elements/audio'
53
+ require 'druid/elements/video'
54
+ require 'druid/elements/bold'
55
+ require 'druid/elements/italic'
@@ -0,0 +1,12 @@
1
+ module Druid
2
+ module Javascript
3
+ module AngularJS
4
+ #
5
+ # return the number of pending ajax requests
6
+ #
7
+ def self.pending_requests
8
+ 'return angular.element(document.body).injector().get(\'$http\').pendingRequests.length;'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Druid
2
+ module Javascript
3
+ module JQuery
4
+ #
5
+ # return the number of pending ajax requests
6
+ #
7
+ def self.pending_requests
8
+ 'return jQuery.active'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Druid
2
+ module Javascript
3
+ module Prototype
4
+ #
5
+ # return the number of pending ajax requests
6
+ #
7
+ def self.pending_requests
8
+ 'return Ajax.activeRequestCount'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module Druid
2
+ module Javascript
3
+
4
+ module YUI
5
+ #
6
+ # return the number of pending ajax requests
7
+ #
8
+ def self.pending_requests
9
+ "var inProgress=0
10
+ for(var i=0; i < YAHOO.util.Connect._transaction_id; i++) {
11
+ if(YAHOO.util.Connect.isCallInProgress(i))
12
+ inProgress++;
13
+ }
14
+ return inProgress;"
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,76 @@
1
+ require 'druid/javascript/jquery'
2
+ require 'druid/javascript/prototype'
3
+ require 'druid/javascript/yui'
4
+ require 'druid/javascript/angularjs'
5
+
6
+ module Druid
7
+ #
8
+ # Provide hooks into different common Javascript Frameworks.
9
+ # Currently this module only supports jQuery and Prototype but it
10
+ # has ability for you to plug your own framework into it and
11
+ # therefore have it work with this gem. You do this by calling the
12
+ # #add_framework method. The module you provide must implement the
13
+ # necessary methods. Please look at the jQuery or Prototype
14
+ # implementations to determine the necessary methods
15
+ #
16
+ module JavascriptFrameworkFacade
17
+
18
+ class << self
19
+ #
20
+ # Set the framework to use
21
+ #
22
+ # @param [Symbol] the framework to use. :jquery and :prototype, :yui,
23
+ # and :angularjs are supported
24
+ #
25
+ def framework=(framework)
26
+ initialize_script_builder unless @builder
27
+ raise unknown_framework(framework) unless @builder[framework]
28
+ @framework = framework
29
+ end
30
+
31
+ def add_framework(key, value)
32
+ raise invalid_framework unless value.respond_to? :pending_requests
33
+ initialize_script_builder unless @builder
34
+ @builder[key] = value
35
+ end
36
+
37
+ #
38
+ # Get the framework that will be used
39
+ #
40
+ def framework
41
+ @framework
42
+ end
43
+
44
+ def script_builder
45
+ initialize_script_builder unless @builder
46
+ @builder[@framework]
47
+ end
48
+
49
+ #
50
+ # get the javascript to determine number of pending requests
51
+ #
52
+ def pending_requests
53
+ script_builder.pending_requests
54
+ end
55
+
56
+ private
57
+
58
+ def initialize_script_builder
59
+ @builder = {
60
+ :jquery => Druid::Javascript::JQuery,
61
+ :prototype => Druid::Javascript::Prototype,
62
+ :yui => Druid::Javascript::YUI,
63
+ :angularjs => Druid::Javascript::AngularJS
64
+ }
65
+ end
66
+
67
+ def unknown_framework(framework)
68
+ "You specified the Javascript framework #{framework} and it is unknown to the system"
69
+ end
70
+
71
+ def invalid_framework
72
+ "The Javascript framework you provided does not implement the necessary methods"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,181 @@
1
+ module Druid
2
+ module LocatorGenerator
3
+
4
+ BASIC_ELEMENTS = %i(
5
+ abbr
6
+ address
7
+ animate
8
+ animate_motion
9
+ animate_transform
10
+ article
11
+ as
12
+ aside
13
+ base
14
+ bdi
15
+ bdo
16
+ blockquote
17
+ body
18
+ br
19
+ caption
20
+ circle
21
+ cite
22
+ code
23
+ col
24
+ colgroup
25
+ command
26
+ cursor
27
+ data
28
+ datalist
29
+ dd
30
+ defs
31
+ del
32
+ desc
33
+ details
34
+ dfn
35
+ dialog
36
+ discard
37
+ dl
38
+ dt
39
+ ellipse
40
+ em
41
+ embed
42
+ fieldset
43
+ figcaption
44
+ figure
45
+ font
46
+ footer
47
+ foreign_object
48
+ g
49
+ head
50
+ header
51
+ hgroup
52
+ hr
53
+ html
54
+ ins
55
+ kbd
56
+ keygen
57
+ legend
58
+ line
59
+ linear_gradient
60
+ main
61
+ map
62
+ mark
63
+ marker
64
+ menu
65
+ menuitem
66
+ mesh_gradient
67
+ mesh_patch
68
+ mesh_row
69
+ meta
70
+ metadata
71
+ meter
72
+ mpath
73
+ nav
74
+ noscript
75
+ object
76
+ optgroup
77
+ output
78
+ p
79
+ param
80
+ path
81
+ pattern
82
+ polygon
83
+ polyline
84
+ pre
85
+ progress
86
+ q
87
+ radial_gradient
88
+ rect
89
+ rp
90
+ rt
91
+ ruby
92
+ s
93
+ samp
94
+ script
95
+ section
96
+ set
97
+ small
98
+ source
99
+ stop
100
+ strong
101
+ style
102
+ sub
103
+ summary
104
+ sup
105
+ switch
106
+ symbol
107
+ template
108
+ text_path
109
+ thread
110
+ time
111
+ title
112
+ track
113
+ tspan
114
+ u
115
+ use
116
+ var
117
+ view
118
+ wbr
119
+ )
120
+
121
+
122
+ ADVANCED_ELEMENTS = %i(
123
+ text_field
124
+ hidden_field
125
+ text_area
126
+ select_list
127
+ link
128
+ checkbox
129
+ radio_button
130
+ button
131
+ div
132
+ span
133
+ table
134
+ cell
135
+ row
136
+ image
137
+ form
138
+ list_item
139
+ ordered_list
140
+ unordered_list
141
+ h1
142
+ h2
143
+ h3
144
+ h4
145
+ h5
146
+ h6
147
+ paragraph
148
+ label
149
+ file_field
150
+ area
151
+ canvas
152
+ audio
153
+ video
154
+ b
155
+ i
156
+ svg
157
+ )
158
+
159
+ def self.generate_locators(target)
160
+ ADVANCED_ELEMENTS.each do |tag|
161
+ target.send(:define_method, "#{tag.to_s}_element") do |*identifier|
162
+ self.send "#{tag.to_s}_for", locator(identifier).clone
163
+ end
164
+
165
+ target.send(:define_method, "#{tag.to_s}_elements") do |*identifier|
166
+ self.send "#{tag.to_s}s_for", identifier[0] ? identifier[0].clone : {}
167
+ end
168
+ end
169
+
170
+ BASIC_ELEMENTS.each do |tag|
171
+ target.send(:define_method, "#{tag.to_s}_element") do |*identifier|
172
+ self.send :element_for, tag, locator(identifier)
173
+ end
174
+
175
+ target.send(:define_method, "#{tag.to_s}_elements") do |*identifier|
176
+ self.send(:elements_for, tag, identifier[0] ? identifier[0] : {})
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,56 @@
1
+ require 'druid/locator_generator'
2
+
3
+ module Druid
4
+ module NestedElements
5
+
6
+ def self.included(cls)
7
+ Druid::LocatorGenerator.generate_locators(cls)
8
+ end
9
+
10
+ private
11
+
12
+ def locator(identifier)
13
+ identifier[0] ? identifier[0] : {:index => 0}
14
+ end
15
+
16
+ # [:text_field,
17
+ # :hidden_field,
18
+ # :text_area,
19
+ # :select_list,
20
+ # :link,
21
+ # :checkbox,
22
+ # :radio_button,
23
+ # :button,
24
+ # :div,
25
+ # :span,
26
+ # :table,
27
+ # :cell,
28
+ # :image,
29
+ # :form,
30
+ # :list_item,
31
+ # :unordered_list,
32
+ # :ordered_list,
33
+ # :h1,
34
+ # :h2,
35
+ # :h3,
36
+ # :h4,
37
+ # :h5,
38
+ # :h6,
39
+ # :paragraph,
40
+ # :label,
41
+ # :file_field,
42
+ # :area,
43
+ # :canvas,
44
+ # :audio,
45
+ # :video].each do |tag|
46
+ # define_method("#{tag.to_s}_element") do |*identifier|
47
+ # self.send "#{tag.to_s}_for", locator(identifier)
48
+ # end
49
+ #
50
+ # define_method("#{tag.to_s}_elements") do |*identifier|
51
+ # self.send "#{tag.to_s}s_for", locator(identifier)
52
+ # end
53
+ # end
54
+
55
+ end
56
+ end
@@ -0,0 +1,115 @@
1
+ require 'page_navigation'
2
+
3
+ module Druid
4
+ #
5
+ # Module to facilitate to creating of page objects in step definitions. You
6
+ # can make the methods below available to all of your step definitions by adding
7
+ # this module to World. This idea was first discussed in Alister Scott's blog
8
+ # entry http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/.
9
+ #
10
+ # @example Making the PageFactory available to your step definitions
11
+ # World Druid::PageFactory
12
+ #
13
+ # @example Visiting a page for the first time in a Scenario
14
+ # visit_page MyPageObject do |page|
15
+ # page.name = 'Tim'
16
+ # end
17
+ #
18
+ # @example using a page that has already been visited in a Scenario
19
+ # on_page MyPageObject do |page|
20
+ # page.name.should == 'Tim'
21
+ # end
22
+ #
23
+ # If you plan to use the navigate_to method you will need to ensure you setup the possible
24
+ # routes ahead of time. You must always have a default route in order for this to work. Here
25
+ # is an example of how you define routes:
26
+ #
27
+ # @example Example routes defined in env.rb
28
+ # Druid::PageFactory.routes = {
29
+ # :default => [[PageOne,:method1], [PageTwoA,:method2], [PageThree,:method3],
30
+ # :another_route => [[PageOne,:method1,"arg1"], [PageTwoB,:method2b], [PageThree,:method3]]
31
+ # }
32
+ # Notice the first entry of :another_route is passing an argument
33
+ # to the method
34
+ # You must also call the navigation_method on each page.
35
+ module PageFactory
36
+ include PageNavigation
37
+ # attr_accessor :page
38
+ #
39
+ # Create and navigate to a page object. The navigation will only work if the
40
+ # 'page_url' method was call on the page object.
41
+ #
42
+ # @param [PageObject, String] a class that has included the
43
+ # Druid module or a string containing the name of the class
44
+ # @param Hash values that is pass through to page class a
45
+ # available in the @params instance variable
46
+ # @param an optional block to be called
47
+ # @return [PageObject] the newly created page object
48
+ #
49
+ def visit_page(page_class, params={:using_params => {}}, &block)
50
+ on_page page_class, params, true, &block
51
+ end
52
+
53
+ # Support 'visit' for readability of usage
54
+ alias_method :visit, :visit_page
55
+ #
56
+ # Create a page object.
57
+ #
58
+ # @param [PageObject, String] a class that has included the Druid module or a string containing the name of the class
59
+ # @param Hash values that is pass through to page class a
60
+ # available in the @params instance variable.
61
+ # @param [Bool] should the page be visited? default is false.
62
+ # @param an optional block to be called
63
+ # @return [PageObject] the newly created page object
64
+ #
65
+ def on_page(page_class, params={:using_params => {}}, visit=false, &block)
66
+ page_class = class_from_string(page_class) if page_class.is_a? String
67
+ return super(page_class, params, visit, &block) unless page_class.ancestors.include? Druid
68
+ merged = page_class.params.merge(params[:using_params])
69
+ page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
70
+ @current_page = page_class.new(@driver, visit)
71
+ block.call @current_page if block
72
+ @current_page
73
+ end
74
+
75
+ # Support 'on' for readability of usage
76
+ alias_method :on, :on_page
77
+
78
+ #
79
+ # Create a page object if and only if the current page is the same page to be created
80
+ #
81
+ # @example
82
+ # original:
83
+ # on_page(NewProduct).save if @current_page.class == NewProduct
84
+ # on_page(EditProduct).save if @current_page.class == EditProduct
85
+ # new:
86
+ # if_page NewProduct do |page|
87
+ # page.save
88
+ # end
89
+ # if_page EditProduct do |page|
90
+ # page.update
91
+ # end
92
+ # @param [PageObject, String] a class that has included the Druid module or a string containing the name of the class
93
+ # @param Hash values that is pass through to page class a
94
+ # available in the @params instance variable
95
+ # @param [block] an optional block to be called
96
+ # @return [PageObject] the newly created page object
97
+ def if_page(page_class, params={:using_params => {}}, &block)
98
+ page_class = class_from_string(page_class) if page_class.is_a? String
99
+ return @current_page unless @current_page.class == page_class
100
+ on_page(page_class, params, false, &block)
101
+ end
102
+
103
+ # support 'if' for readability of usage
104
+ alias_method :if, :if_page
105
+
106
+ private
107
+
108
+ def class_from_string(str)
109
+ str.split('::').inject(Object) do |mod, class_name|
110
+ mod.const_get(class_name)
111
+ end
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,104 @@
1
+ module Druid
2
+ module PagePopulator
3
+ #
4
+ # This method will populate all matched page TextFields,
5
+ # TextAreas, SelectLists, FileFields, Checkboxes, and Radio Buttons from the
6
+ # Hash passed as an argument. The way it find an element is by
7
+ # matching the Hash key to the name you provided when declaring
8
+ # the element on your page.
9
+ #
10
+ # Checkbox and Radio Button values must be true or false.
11
+ #
12
+ # @example
13
+ # class ExamplePage
14
+ # include PageObject
15
+ #
16
+ # text_field(:username, :id => 'username_id')
17
+ # checkbox(:active, :id => 'active_id')
18
+ # end
19
+ #
20
+ # ...
21
+ #
22
+ # @browser = Watir::Browser.new :firefox
23
+ # example_page = ExamplePage.new(@browser)
24
+ # example_page.populate_page_with :username => 'a name', :active => true
25
+ #
26
+ # @param data [Hash] the data to use to populate this page. The key
27
+ # can be either a string or a symbol. The value must be a string
28
+ # for TextField, TextArea, SelectList and FileField must be true or
29
+ # false for a Checkbox or RadioButton.
30
+ #
31
+ def populate_page_with(data)
32
+ data.to_h.each do |key, value|
33
+ populate_section(key, value) if value.respond_to?(:to_h)
34
+ populate_value(self, key, value)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def populate_section(section, data)
41
+ return unless self.respond_to? section
42
+ data.to_h.each do |key, value|
43
+ populate_value(self.send(section), key, value)
44
+ end
45
+ end
46
+
47
+ def populate_value(receiver, key, value)
48
+ populate_checkbox(receiver, key, value) if is_checkbox?(receiver, key) and is_enabled?(receiver, key)
49
+ populate_radiobuttongroup(receiver, key, value) if is_radiobuttongroup?(receiver, key)
50
+ populate_radiobutton(receiver, key, value) if is_radiobutton?(receiver, key) and is_enabled?(receiver, key)
51
+ populate_select_list(receiver, key, value) if is_select_list?(receiver, key)
52
+ populate_text(receiver, key, value) if is_text?(receiver, key) and is_enabled?(receiver, key)
53
+ end
54
+
55
+ def populate_text(receiver, key, value)
56
+ receiver.send "#{key}=", value
57
+ end
58
+
59
+ def populate_checkbox(receiver, key, value)
60
+ return receiver.send "check_#{key}" if value
61
+ return receiver.send "uncheck_#{key}"
62
+ end
63
+
64
+ def populate_radiobutton(receiver, key, value)
65
+ return receiver.send "select_#{key}" if value
66
+ end
67
+
68
+ def populate_radiobuttongroup(receiver, key, value)
69
+ return receiver.send "select_#{key}", value
70
+ end
71
+
72
+ def populate_select_list(receiver, key, value)
73
+ receiver.send "#{key}=", value
74
+ end
75
+
76
+ def is_text?(receiver, key)
77
+ return false if is_select_list?(receiver, key)
78
+ receiver.respond_to?("#{key}=".to_sym)
79
+ end
80
+
81
+ def is_checkbox?(receiver, key)
82
+ receiver.respond_to?("check_#{key}".to_sym)
83
+ end
84
+
85
+ def is_radiobutton?(receiver, key)
86
+ receiver.respond_to?("select_#{key}".to_sym)
87
+ end
88
+
89
+ def is_radiobuttongroup?(receiver, key)
90
+ receiver.respond_to?("select_#{key}".to_sym) and receiver.respond_to?("#{key}_values")
91
+ end
92
+
93
+ def is_select_list?(receiver, key)
94
+ receiver.respond_to?("#{key}_options".to_sym)
95
+ end
96
+
97
+ def is_enabled?(receiver, key)
98
+ return false if is_radiobuttongroup?(receiver, key)
99
+ return true if (receiver.send "#{key}_element").tag_name == "textarea"
100
+ element = receiver.send("#{key}_element")
101
+ element.enabled? and element.present?
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,17 @@
1
+ module Druid
2
+ class SectionCollection < Array
3
+
4
+ def find_by values_hash
5
+ find do |section|
6
+ values_hash.all? { |key, value| value === section.public_send(key) }
7
+ end
8
+ end
9
+
10
+ def select_by values_hash
11
+ matches = select do |section|
12
+ values_hash.all? { |key, value| value === section.public_send(key) }
13
+ end
14
+ self.class[*matches]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Druid
2
+ VERSION = "1.0.0"
3
+ end