druid-s 1.0.0

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