page_object 1.1.1

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 (272) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/ChangeLog +809 -0
  8. data/Gemfile +14 -0
  9. data/Guardfile +20 -0
  10. data/LICENSE +20 -0
  11. data/README.md +111 -0
  12. data/Rakefile +35 -0
  13. data/cucumber.yml +10 -0
  14. data/features/area.feature +35 -0
  15. data/features/async.feature +30 -0
  16. data/features/audio.feature +68 -0
  17. data/features/bold.feature +21 -0
  18. data/features/button.feature +98 -0
  19. data/features/canvas.feature +37 -0
  20. data/features/check_box.feature +55 -0
  21. data/features/div.feature +45 -0
  22. data/features/element.feature +322 -0
  23. data/features/file_field.feature +40 -0
  24. data/features/form.feature +43 -0
  25. data/features/frames.feature +75 -0
  26. data/features/generic_elements.feature +29 -0
  27. data/features/gxt_table_extension.feature +24 -0
  28. data/features/headings.feature +97 -0
  29. data/features/hidden_field.feature +45 -0
  30. data/features/html/04-Death_Becomes_Fur.mp4 +0 -0
  31. data/features/html/04-Death_Becomes_Fur.oga +0 -0
  32. data/features/html/async.html +36 -0
  33. data/features/html/double_click.html +13 -0
  34. data/features/html/failure.html +8 -0
  35. data/features/html/frame_1.html +18 -0
  36. data/features/html/frame_2.html +16 -0
  37. data/features/html/frame_3.html +14 -0
  38. data/features/html/frames.html +12 -0
  39. data/features/html/hover.html +12 -0
  40. data/features/html/iframes.html +12 -0
  41. data/features/html/images/circle.png +0 -0
  42. data/features/html/images/img_pulpit.jpg +0 -0
  43. data/features/html/images/submit.gif +0 -0
  44. data/features/html/indexed_property.html +55 -0
  45. data/features/html/modal.html +17 -0
  46. data/features/html/modal_1.html +38 -0
  47. data/features/html/modal_2.html +27 -0
  48. data/features/html/movie.mp4 +0 -0
  49. data/features/html/movie.ogg +0 -0
  50. data/features/html/multi_elements.html +144 -0
  51. data/features/html/nested_elements.html +77 -0
  52. data/features/html/nested_frame_1.html +1 -0
  53. data/features/html/nested_frame_2.html +11 -0
  54. data/features/html/nested_frame_3.html +14 -0
  55. data/features/html/nested_frames.html +10 -0
  56. data/features/html/planets.gif +0 -0
  57. data/features/html/static_elements.html +207 -0
  58. data/features/html/success.html +8 -0
  59. data/features/html/sun.gif +0 -0
  60. data/features/html/sun.html +7 -0
  61. data/features/image.feature +50 -0
  62. data/features/indexed_property.feature +117 -0
  63. data/features/javascript.feature +28 -0
  64. data/features/label.feature +46 -0
  65. data/features/link.feature +52 -0
  66. data/features/list_item.feature +36 -0
  67. data/features/modal_dialog.feature +15 -0
  68. data/features/multi_elements.feature +492 -0
  69. data/features/nested_elements.feature +117 -0
  70. data/features/ordered_list.feature +56 -0
  71. data/features/page_level_actions.feature +90 -0
  72. data/features/paragraph.feature +35 -0
  73. data/features/radio_button.feature +58 -0
  74. data/features/radio_button_group.feature +29 -0
  75. data/features/sample-app/public/jquery-1.3.2.js +4376 -0
  76. data/features/sample-app/public/jquery.html +30 -0
  77. data/features/sample-app/public/prototype-1.6.0.3.js +4320 -0
  78. data/features/sample-app/public/prototype.html +35 -0
  79. data/features/sample-app/sample_app.rb +35 -0
  80. data/features/section.feature +132 -0
  81. data/features/select_list.feature +86 -0
  82. data/features/span.feature +37 -0
  83. data/features/step_definitions/accessor_steps.rb +64 -0
  84. data/features/step_definitions/area_steps.rb +19 -0
  85. data/features/step_definitions/async_steps.rb +83 -0
  86. data/features/step_definitions/audio_steps.rb +27 -0
  87. data/features/step_definitions/bold_steps.rb +12 -0
  88. data/features/step_definitions/button_steps.rb +48 -0
  89. data/features/step_definitions/canvas_steps.rb +15 -0
  90. data/features/step_definitions/check_box_steps.rb +35 -0
  91. data/features/step_definitions/div_steps.rb +19 -0
  92. data/features/step_definitions/element_steps.rb +266 -0
  93. data/features/step_definitions/file_field_steps.rb +19 -0
  94. data/features/step_definitions/form_steps.rb +19 -0
  95. data/features/step_definitions/frames_steps.rb +159 -0
  96. data/features/step_definitions/generic_element_steps.rb +31 -0
  97. data/features/step_definitions/gxt_table_steps.rb +58 -0
  98. data/features/step_definitions/headings_steps.rb +12 -0
  99. data/features/step_definitions/hidden_field_steps.rb +27 -0
  100. data/features/step_definitions/image_steps.rb +27 -0
  101. data/features/step_definitions/indexed_property_steps.rb +163 -0
  102. data/features/step_definitions/javascript_steps.rb +53 -0
  103. data/features/step_definitions/label_steps.rb +19 -0
  104. data/features/step_definitions/link_steps.rb +40 -0
  105. data/features/step_definitions/list_item_steps.rb +19 -0
  106. data/features/step_definitions/modal_dialog_steps.rb +62 -0
  107. data/features/step_definitions/multi_elements_steps.rb +541 -0
  108. data/features/step_definitions/nested_elements_steps.rb +212 -0
  109. data/features/step_definitions/ordered_list_steps.rb +23 -0
  110. data/features/step_definitions/page_level_actions_steps.rb +135 -0
  111. data/features/step_definitions/page_traversal_steps.rb +4 -0
  112. data/features/step_definitions/paragraph_steps.rb +28 -0
  113. data/features/step_definitions/radio_button_group_steps.rb +36 -0
  114. data/features/step_definitions/radio_button_steps.rb +27 -0
  115. data/features/step_definitions/section_steps.rb +268 -0
  116. data/features/step_definitions/select_list_steps.rb +65 -0
  117. data/features/step_definitions/span_steps.rb +19 -0
  118. data/features/step_definitions/table_cell_steps.rb +15 -0
  119. data/features/step_definitions/table_row_steps.rb +23 -0
  120. data/features/step_definitions/table_steps.rb +70 -0
  121. data/features/step_definitions/text_area_steps.rb +35 -0
  122. data/features/step_definitions/text_field_steps.rb +35 -0
  123. data/features/step_definitions/unordered_list_steps.rb +23 -0
  124. data/features/step_definitions/video_steps.rb +45 -0
  125. data/features/support/ajax_text_environment.rb +26 -0
  126. data/features/support/env.rb +8 -0
  127. data/features/support/hooks.rb +8 -0
  128. data/features/support/page.rb +382 -0
  129. data/features/support/persistent_browser.rb +70 -0
  130. data/features/support/targets/firefox14_osx.rb +6 -0
  131. data/features/support/targets/firefox14_windows7.rb +6 -0
  132. data/features/support/url_helper.rb +57 -0
  133. data/features/table.feature +122 -0
  134. data/features/table_cell.feature +45 -0
  135. data/features/table_row.feature +43 -0
  136. data/features/text_area.feature +51 -0
  137. data/features/text_field.feature +70 -0
  138. data/features/unordered_list.feature +56 -0
  139. data/features/video.feature +73 -0
  140. data/lib/page-object.rb +421 -0
  141. data/lib/page-object/accessors.rb +1412 -0
  142. data/lib/page-object/core_ext/string.rb +5 -0
  143. data/lib/page-object/element_locators.rb +21 -0
  144. data/lib/page-object/elements.rb +60 -0
  145. data/lib/page-object/elements/area.rb +31 -0
  146. data/lib/page-object/elements/audio.rb +9 -0
  147. data/lib/page-object/elements/bold.rb +11 -0
  148. data/lib/page-object/elements/button.rb +35 -0
  149. data/lib/page-object/elements/canvas.rb +23 -0
  150. data/lib/page-object/elements/check_box.rb +37 -0
  151. data/lib/page-object/elements/div.rb +19 -0
  152. data/lib/page-object/elements/element.rb +226 -0
  153. data/lib/page-object/elements/file_field.rb +38 -0
  154. data/lib/page-object/elements/form.rb +36 -0
  155. data/lib/page-object/elements/heading.rb +15 -0
  156. data/lib/page-object/elements/hidden_field.rb +22 -0
  157. data/lib/page-object/elements/image.rb +36 -0
  158. data/lib/page-object/elements/label.rb +19 -0
  159. data/lib/page-object/elements/link.rb +46 -0
  160. data/lib/page-object/elements/list_item.rb +19 -0
  161. data/lib/page-object/elements/media.rb +45 -0
  162. data/lib/page-object/elements/option.rb +10 -0
  163. data/lib/page-object/elements/ordered_list.rb +50 -0
  164. data/lib/page-object/elements/paragraph.rb +9 -0
  165. data/lib/page-object/elements/radio_button.rb +37 -0
  166. data/lib/page-object/elements/select_list.rb +42 -0
  167. data/lib/page-object/elements/span.rb +19 -0
  168. data/lib/page-object/elements/table.rb +79 -0
  169. data/lib/page-object/elements/table_cell.rb +28 -0
  170. data/lib/page-object/elements/table_row.rb +50 -0
  171. data/lib/page-object/elements/text_area.rb +38 -0
  172. data/lib/page-object/elements/text_field.rb +42 -0
  173. data/lib/page-object/elements/unordered_list.rb +51 -0
  174. data/lib/page-object/elements/video.rb +18 -0
  175. data/lib/page-object/indexed_properties.rb +40 -0
  176. data/lib/page-object/javascript/angularjs.rb +14 -0
  177. data/lib/page-object/javascript/jquery.rb +14 -0
  178. data/lib/page-object/javascript/prototype.rb +14 -0
  179. data/lib/page-object/javascript/yui.rb +19 -0
  180. data/lib/page-object/javascript_framework_facade.rb +80 -0
  181. data/lib/page-object/loads_platform.rb +45 -0
  182. data/lib/page-object/locator_generator.rb +131 -0
  183. data/lib/page-object/nested_elements.rb +17 -0
  184. data/lib/page-object/page_factory.rb +108 -0
  185. data/lib/page-object/page_populator.rb +83 -0
  186. data/lib/page-object/platforms.rb +18 -0
  187. data/lib/page-object/platforms/selenium_webdriver.rb +30 -0
  188. data/lib/page-object/platforms/selenium_webdriver/button.rb +15 -0
  189. data/lib/page-object/platforms/selenium_webdriver/check_box.rb +29 -0
  190. data/lib/page-object/platforms/selenium_webdriver/element.rb +291 -0
  191. data/lib/page-object/platforms/selenium_webdriver/file_field.rb +16 -0
  192. data/lib/page-object/platforms/selenium_webdriver/form.rb +16 -0
  193. data/lib/page-object/platforms/selenium_webdriver/image.rb +28 -0
  194. data/lib/page-object/platforms/selenium_webdriver/link.rb +23 -0
  195. data/lib/page-object/platforms/selenium_webdriver/ordered_list.rb +39 -0
  196. data/lib/page-object/platforms/selenium_webdriver/page_object.rb +1237 -0
  197. data/lib/page-object/platforms/selenium_webdriver/radio_button.rb +22 -0
  198. data/lib/page-object/platforms/selenium_webdriver/select_list.rb +93 -0
  199. data/lib/page-object/platforms/selenium_webdriver/surrogate_selenium_element.rb +42 -0
  200. data/lib/page-object/platforms/selenium_webdriver/table.rb +42 -0
  201. data/lib/page-object/platforms/selenium_webdriver/table_row.rb +43 -0
  202. data/lib/page-object/platforms/selenium_webdriver/text_area.rb +17 -0
  203. data/lib/page-object/platforms/selenium_webdriver/text_field.rb +17 -0
  204. data/lib/page-object/platforms/selenium_webdriver/unordered_list.rb +39 -0
  205. data/lib/page-object/platforms/watir_webdriver.rb +30 -0
  206. data/lib/page-object/platforms/watir_webdriver/check_box.rb +29 -0
  207. data/lib/page-object/platforms/watir_webdriver/element.rb +249 -0
  208. data/lib/page-object/platforms/watir_webdriver/file_field.rb +16 -0
  209. data/lib/page-object/platforms/watir_webdriver/form.rb +16 -0
  210. data/lib/page-object/platforms/watir_webdriver/image.rb +22 -0
  211. data/lib/page-object/platforms/watir_webdriver/link.rb +15 -0
  212. data/lib/page-object/platforms/watir_webdriver/ordered_list.rb +35 -0
  213. data/lib/page-object/platforms/watir_webdriver/page_object.rb +1082 -0
  214. data/lib/page-object/platforms/watir_webdriver/radio_button.rb +22 -0
  215. data/lib/page-object/platforms/watir_webdriver/select_list.rb +74 -0
  216. data/lib/page-object/platforms/watir_webdriver/table.rb +38 -0
  217. data/lib/page-object/platforms/watir_webdriver/table_row.rb +37 -0
  218. data/lib/page-object/platforms/watir_webdriver/text_area.rb +23 -0
  219. data/lib/page-object/platforms/watir_webdriver/text_field.rb +16 -0
  220. data/lib/page-object/platforms/watir_webdriver/unordered_list.rb +36 -0
  221. data/lib/page-object/sections.rb +29 -0
  222. data/lib/page-object/version.rb +4 -0
  223. data/lib/page-object/widgets.rb +133 -0
  224. data/page_object.gemspec +31 -0
  225. data/pageobject.gems +1 -0
  226. data/spec/page-object/accessors_spec.rb +40 -0
  227. data/spec/page-object/element_locators_spec.rb +1122 -0
  228. data/spec/page-object/elements/area_spec.rb +45 -0
  229. data/spec/page-object/elements/bold_spec.rb +29 -0
  230. data/spec/page-object/elements/button_spec.rb +64 -0
  231. data/spec/page-object/elements/canvas_spec.rb +40 -0
  232. data/spec/page-object/elements/check_box_spec.rb +49 -0
  233. data/spec/page-object/elements/div_spec.rb +28 -0
  234. data/spec/page-object/elements/element_spec.rb +114 -0
  235. data/spec/page-object/elements/file_field_spec.rb +39 -0
  236. data/spec/page-object/elements/form_spec.rb +28 -0
  237. data/spec/page-object/elements/heading_spec.rb +48 -0
  238. data/spec/page-object/elements/hidden_field_spec.rb +28 -0
  239. data/spec/page-object/elements/image_spec.rb +66 -0
  240. data/spec/page-object/elements/label_spec.rb +29 -0
  241. data/spec/page-object/elements/link_spec.rb +49 -0
  242. data/spec/page-object/elements/list_item_spec.rb +29 -0
  243. data/spec/page-object/elements/nested_element_spec.rb +254 -0
  244. data/spec/page-object/elements/option_spec.rb +11 -0
  245. data/spec/page-object/elements/ordered_list_spec.rb +94 -0
  246. data/spec/page-object/elements/paragraph_spec.rb +27 -0
  247. data/spec/page-object/elements/select_list_spec.rb +142 -0
  248. data/spec/page-object/elements/selenium/radio_button_spec.rb +44 -0
  249. data/spec/page-object/elements/selenium/text_field_spec.rb +49 -0
  250. data/spec/page-object/elements/selenium_element_spec.rb +177 -0
  251. data/spec/page-object/elements/span_spec.rb +26 -0
  252. data/spec/page-object/elements/table_cell_spec.rb +21 -0
  253. data/spec/page-object/elements/table_row_spec.rb +70 -0
  254. data/spec/page-object/elements/table_spec.rb +98 -0
  255. data/spec/page-object/elements/text_area_spec.rb +39 -0
  256. data/spec/page-object/elements/unordered_list_spec.rb +94 -0
  257. data/spec/page-object/elements/watir_element_spec.rb +145 -0
  258. data/spec/page-object/javascript_framework_facade_spec.rb +61 -0
  259. data/spec/page-object/loads_platform_spec.rb +53 -0
  260. data/spec/page-object/page-object_spec.rb +407 -0
  261. data/spec/page-object/page_factory_spec.rb +238 -0
  262. data/spec/page-object/page_populator_spec.rb +122 -0
  263. data/spec/page-object/page_section_spec.rb +73 -0
  264. data/spec/page-object/platforms/selenium_webdriver/selenium_page_object_spec.rb +68 -0
  265. data/spec/page-object/platforms/selenium_webdriver_spec.rb +29 -0
  266. data/spec/page-object/platforms/watir_webdriver/watir_page_object_spec.rb +29 -0
  267. data/spec/page-object/platforms/watir_webdriver_spec.rb +9 -0
  268. data/spec/page-object/selenium_accessors_spec.rb +609 -0
  269. data/spec/page-object/watir_accessors_spec.rb +1134 -0
  270. data/spec/page-object/widget_spec.rb +226 -0
  271. data/spec/spec_helper.rb +47 -0
  272. metadata +601 -0
@@ -0,0 +1,56 @@
1
+ Feature: Unordered list
2
+
3
+ Background:
4
+ Given I am on the static elements page
5
+
6
+ Scenario: Getting the first element from the unordered list
7
+ When I get the first item from the unordered list
8
+ Then the list items text should be "Item One"
9
+
10
+ Scenario Outline: Locating unordered lists on the page
11
+ When I search for the unordered list by "<search_by>"
12
+ And I get the first item from the list
13
+ Then the list items text should be "Item One"
14
+ And the list should contain 3 items
15
+ And each item should contain "Item"
16
+
17
+ Scenarios:
18
+ | search_by |
19
+ | id |
20
+ | class |
21
+ | xpath |
22
+ | index |
23
+ | name |
24
+
25
+ @selenium_only
26
+ Scenario Outline: Locating unordered lists on the page
27
+ When I search for the unordered list by "<search_by>"
28
+ And I get the first item from the list
29
+ Then the list items text should be "Item One"
30
+ And the list should contain 3 items
31
+ And each item should contain "Item"
32
+
33
+ Scenarios:
34
+ | search_by |
35
+ | css |
36
+
37
+ Scenario Outline: Locating unordered lists using multiple parameters
38
+ When I search for the unordered list by "<param1>" and "<param2>"
39
+ And I get the first item from the list
40
+ Then the list items text should be "Item One"
41
+
42
+ Scenarios:
43
+ | param1 | param2 |
44
+ | class | index |
45
+ | name | index |
46
+
47
+ Scenario: Finding a unordered list dynamically
48
+ When I search for the unordered list while the script is executing
49
+ Then I should see that the unordered list exists
50
+ When I get the first item from the list
51
+ Then the list items text should be "Item One"
52
+
53
+ Scenario: Getting the text from an unordered list
54
+ Then the text for the unordered list should contain "Item One"
55
+ And the text for the unordered list should contain "Item Two"
56
+ And the text for the unordered list should contain "Item Three"
@@ -0,0 +1,73 @@
1
+ Feature: Support for video element
2
+
3
+ Background:
4
+ Given I am on the static elements page
5
+
6
+ Scenario: finding an video element
7
+ When I retrieve the video element
8
+ Then I should know it exists
9
+ And I should know it is visible
10
+
11
+ Scenario Outline: Locating a video element on the page
12
+ When I search for the video element by "<search_by>"
13
+ Then I should know it is visible
14
+
15
+ Examples:
16
+ | search_by |
17
+ | id |
18
+ | class |
19
+ | name |
20
+ | xpath |
21
+ | index |
22
+ | css |
23
+
24
+ Scenario Outline: Locating videos using multiple parameters
25
+ When I search for the video element by "<param1>" and "<param2>"
26
+ Then I should know it is visible
27
+
28
+ Examples:
29
+ | param1 | param2 |
30
+ | class | index |
31
+ | name | index |
32
+
33
+ Scenario: Should know if it is autoplay
34
+ When I retrieve the video element
35
+ Then I should know the video is not autoplay
36
+
37
+ Scenario: Should know if the controls are displayed
38
+ When I retrieve the video element
39
+ Then I should know that the controls are displayed
40
+
41
+ Scenario: Should know if it is paused
42
+ When I retrieve the video element
43
+ Then I should know that the video is paused
44
+
45
+ Scenario: Should know its duration
46
+ When I retrieve the video element
47
+ Then I should know that the duration is greater than 12 seconds
48
+
49
+ Scenario: Should know its volume
50
+ When I retrieve the video element
51
+ Then I should know that its volume is 1
52
+
53
+ Scenario: Should know its height and width
54
+ When I retrieve the video element
55
+ Then I should know that its height is 240 pixels
56
+ And I should knot what its width is 320 pixels
57
+
58
+ Scenario: Should know if it has ended
59
+ When I retrieve the video element
60
+ Then I should know that it has not ended
61
+
62
+ Scenario: Should know if it is seeking
63
+ When I retrieve the video element
64
+ Then I should know that it is not seeking
65
+
66
+ Scenario: Should know if it is in a loop
67
+ When I retrieve the video element
68
+ Then I should know that it is not in a loop
69
+
70
+ Scenario: Should know if it is muted
71
+ When I retrieve the video element
72
+ Then I should know that it is muted
73
+
@@ -0,0 +1,421 @@
1
+ require 'page-object/version'
2
+ require 'page-object/accessors'
3
+ require 'page-object/platforms'
4
+ require 'page-object/element_locators'
5
+ require 'page-object/nested_elements'
6
+ require 'page-object/page_factory'
7
+ require 'page-object/page_populator'
8
+ require 'page-object/javascript_framework_facade'
9
+ require 'page-object/indexed_properties'
10
+ require 'page-object/sections'
11
+ require 'page-object/widgets'
12
+
13
+ require 'watir-webdriver'
14
+ require 'page-object/platforms/watir_webdriver/element'
15
+ require 'page-object/platforms/watir_webdriver/page_object'
16
+ require 'page-object/platforms/selenium_webdriver/element'
17
+ require 'page-object/platforms/selenium_webdriver/page_object'
18
+
19
+ require 'selenium/webdriver/common/error'
20
+ #
21
+ # Module that when included adds functionality to a page object. This module
22
+ # will add numerous class and instance methods that you use to define and
23
+ # interact with web pages.
24
+ #
25
+ # If we have a login page with a username and password textfield and a login
26
+ # button we might define our page like the one below. We can then interact with
27
+ # the object using the generated methods.
28
+ #
29
+ # @example Login page example
30
+ # class LoginPage
31
+ # include PageObject
32
+ #
33
+ # text_field(:username, :id => 'user')
34
+ # text_field(:password, :id => 'pass')
35
+ # button(:login, :value => 'Login')
36
+ # end
37
+ #
38
+ # ...
39
+ #
40
+ # browser = Watir::Browser.new :firefox
41
+ # login_page = LoginPage.new(browser)
42
+ # login_page.username = 'cheezy'
43
+ # login_page.password = 'secret'
44
+ # login_page.login
45
+ #
46
+ # @see PageObject::Accessors to see what class level methods are added to this module at runtime.
47
+ #
48
+ module PageObject
49
+ include LoadsPlatform
50
+ include ElementLocators
51
+ include PagePopulator
52
+
53
+ # @return [Watir::Browser or Selenium::WebDriver::Driver] the platform browser passed to the constructor
54
+ attr_reader :browser
55
+ # @return [PageObject::WatirPageObject or PageObject::SeleniumPageObject] the platform page object
56
+ attr_reader :platform
57
+
58
+ #
59
+ # Construct a new page object. Prior to browser initialization it will call
60
+ # a method named initialize_accessors if it exists. Upon initialization of
61
+ # the page it will call a method named initialize_page if it exists.
62
+ #
63
+ # @param [Watir::Browser, Watir::HTMLElement or Selenium::WebDriver::Driver, Selenium::WebDriver::Element] the platform browser/element to use
64
+ # @param [bool] open the page if page_url is set
65
+ #
66
+ def initialize(root, visit=false)
67
+ initialize_accessors if respond_to?(:initialize_accessors)
68
+ initialize_browser(root)
69
+ goto if visit && respond_to?(:goto)
70
+ initialize_page if respond_to?(:initialize_page)
71
+ end
72
+
73
+ def initialize_browser(root)
74
+ @root_element = root_element_for root, PageObject::Platforms.get
75
+ @browser = browser_for root, PageObject::Platforms.get
76
+ include_platform_driver(root)
77
+ end
78
+
79
+ # @private
80
+ def self.included(cls)
81
+ cls.extend PageObject::Accessors
82
+ end
83
+
84
+ #
85
+ # Set the default timeout for page level waits
86
+ #
87
+ def self.default_page_wait=(timeout)
88
+ @page_wait = timeout
89
+ end
90
+
91
+ #
92
+ # Returns the default timeout for page lavel waits
93
+ #
94
+ def self.default_page_wait
95
+ @page_wait ||= 30
96
+ end
97
+
98
+ #
99
+ # Sets the default timeout for element level waits
100
+ #
101
+ def self.default_element_wait=(timeout)
102
+ @element_wait = timeout
103
+ end
104
+
105
+ #
106
+ # Returns the default timeout for element level waits
107
+ #
108
+ def self.default_element_wait
109
+ @element_wait ||= 5
110
+ end
111
+
112
+ #
113
+ # Set the javascript framework to use when determining number of
114
+ # ajax requests. Valid frameworks are :jquery, :prototype, :yui,
115
+ # and :angularjs
116
+ #
117
+ def self.javascript_framework=(framework)
118
+ PageObject::JavascriptFrameworkFacade.framework = framework
119
+ end
120
+
121
+ #
122
+ # Add a new javascript framework to page-object. The module passed
123
+ # in must adhere to the same prototype as the JQuery and Prototype
124
+ # modules.
125
+ #
126
+ # @param [Symbol] the name used to reference the framework in
127
+ # subsequent calls
128
+ # @param [Module] a module that has the necessary methods to perform
129
+ # the required actions.
130
+ #
131
+ def self.add_framework(key, framework)
132
+ PageObject::JavascriptFrameworkFacade.add_framework(key, framework)
133
+ end
134
+
135
+ #
136
+ # get the current page url
137
+ #
138
+ def current_url
139
+ platform.current_url
140
+ end
141
+
142
+ #
143
+ # navigate to the provided url
144
+ #
145
+ # @param [String] the full url to navigate to
146
+ #
147
+ def navigate_to(url)
148
+ platform.navigate_to(url)
149
+ end
150
+
151
+ #
152
+ # Returns the text of the current page
153
+ #
154
+ def text
155
+ root.text
156
+ end
157
+
158
+ #
159
+ # Returns the html of the current page
160
+ #
161
+ def html
162
+ platform.html
163
+ end
164
+
165
+ #
166
+ # Returns the title of the current page
167
+ #
168
+ def title
169
+ platform.title
170
+ end
171
+
172
+ #
173
+ # Wait until the block returns true or times out
174
+ #
175
+ # @example
176
+ # @page.wait_until(5, 'Success not found on page') do
177
+ # @page.text.include? 'Success'
178
+ # end
179
+ #
180
+ # @param [Numeric] the amount of time to wait for the block to return true.
181
+ # @param [String] the message to include with the error if we exceed the timeout duration.
182
+ # @param block the block to execute. It should return true when successful.
183
+ #
184
+ def wait_until(timeout = PageObject.default_page_wait, message = nil, &block)
185
+ platform.wait_until(timeout, message, &block)
186
+ end
187
+
188
+
189
+ #
190
+ # Wait until there are no pending ajax requests. This requires you
191
+ # to set the javascript framework in advance.
192
+ #
193
+ # @param [Numeric] the amount of time to wait for the block to return true.
194
+ # @param [String] the message to include with the error if we exceed
195
+ # the timeout duration.
196
+ #
197
+ def wait_for_ajax(timeout = 30, message = nil)
198
+ end_time = ::Time.now + timeout
199
+ until ::Time.now > end_time
200
+ return if browser.execute_script(::PageObject::JavascriptFrameworkFacade.pending_requests) == 0
201
+ sleep 0.5
202
+ end
203
+ message = "Timed out waiting for ajax requests to complete" unless message
204
+ raise message
205
+ end
206
+
207
+ #
208
+ # Override the normal alert popup so it does not occur.
209
+ #
210
+ # @example
211
+ # message = @page.alert do
212
+ # @page.button_that_causes_alert
213
+ # end
214
+ #
215
+ # @param frame optional parameter used when alert is nested within a frame
216
+ # @param block a block that has the call that will cause the alert to display
217
+ # @return [String] the message that was contained in the alert
218
+ #
219
+ def alert(frame=nil, &block)
220
+ platform.alert(frame, &block)
221
+ end
222
+
223
+ #
224
+ # Override the normal confirm popup so it does not occur.
225
+ #
226
+ # @example
227
+ # message = @popup.confirm(true) do
228
+ # @page.button_that_causes_confirm
229
+ # end
230
+ #
231
+ # @param [bool] what response you want to return back from the confirm popup
232
+ # @param frame optional parameter used when the confirm is nested within a frame
233
+ # @param block a block that has the call that will cause the confirm to display
234
+ # @return [String] the message that was prompted in the confirm
235
+ #
236
+ def confirm(response, frame=nil, &block)
237
+ platform.confirm(response, frame, &block)
238
+ end
239
+
240
+ #
241
+ # Override the normal prompt popup so it does not occur.
242
+ #
243
+ # @example
244
+ # message = @popup.prompt("Some Value") do
245
+ # @page.button_that_causes_prompt
246
+ # end
247
+ #
248
+ # @param [string] the value returned to the caller of the prompt
249
+ # @param frame optional parameter used with the prompt is nested within a frame
250
+ # @param block a block that has the call that will cause the prompt to display
251
+ # @return [Hash] A has containing two keys - :message contains the prompt message and
252
+ # :default_value contains the default value for the prompt if provided
253
+ #
254
+ def prompt(answer, frame=nil, &block)
255
+ platform.prompt(answer, frame, &block)
256
+ end
257
+
258
+ #
259
+ # Execute javascript on the browser
260
+ #
261
+ # @example Get inner HTML of element
262
+ # span = @page.span_element
263
+ # @page.execute_script "return arguments[0].innerHTML", span
264
+ # #=> "Span innerHTML"
265
+ #
266
+ def execute_script(script, *args)
267
+ args.map! { |e| e.kind_of?(PageObject::Elements::Element) ? e.element : e }
268
+ platform.execute_script(script, *args)
269
+ end
270
+
271
+ #
272
+ # Identify an element as existing within a frame. A frame parameter
273
+ # is passed to the block and must be passed to the other calls to PageObject.
274
+ # You can nest calls to in_frame by passing the frame to the next level.
275
+ #
276
+ # @example
277
+ # in_frame(:id => 'frame_id') do |frame|
278
+ # text_field_element(:id => 'fname', :frame => frame)
279
+ # end
280
+ #
281
+ # @param [Hash] identifier how we find the frame. The valid keys are:
282
+ # * :id => Watir and Selenium
283
+ # * :index => Watir and Selenium
284
+ # * :name => Watir and Selenium
285
+ # * :class => Watir only
286
+ # @param frame passed from a previous call to in_frame. Used to nest calls
287
+ # @param block that contains the calls to elements that exist inside the frame.
288
+ #
289
+ def in_frame(identifier, frame=nil, &block)
290
+ platform.in_frame(identifier, frame, &block)
291
+ end
292
+
293
+ # Identify an element as existing within an iframe. A frame parameter
294
+ # is passed to the block and must be passed to the other calls to PageObject.
295
+ # You can nest calls to in_iframe by passing the frame to the next level.
296
+ #
297
+ # @example
298
+ # in_iframe(:id => 'iframe_id') do |iframe|
299
+ # text_field_element(:id => 'ifname', :frame => iframe)
300
+ # end
301
+ #
302
+ # @param [Hash] identifier how we find the iframe. The valid keys are:
303
+ # * :id => Watir and Selenium
304
+ # * :index => Watir and Selenium
305
+ # * :name => Watir and Selenium
306
+ # * :class => Watir only
307
+ # @param frame passed from a previous call to in_iframe. Used to nest calls
308
+ # @param block that contains the calls to elements that exist inside the iframe.
309
+ #
310
+ def in_iframe(identifier, frame=nil, &block)
311
+ platform.in_iframe(identifier, frame, &block)
312
+ end
313
+
314
+ #
315
+ # Override the normal showModalDialog call is it opens a window instead
316
+ # of a dialog. You will need to attach to the new window in order to
317
+ # continue.
318
+ #
319
+ # @example
320
+ # @page.modal_dialog do
321
+ # @page.action_that_spawns_the_modal
322
+ # end
323
+ #
324
+ # @param block a block that contains the call that will cause the modal dialog.
325
+ #
326
+ def modal_dialog(&block)
327
+ script =
328
+ %Q{
329
+ window.showModalDialog = function(sURL, vArguments, sFeatures) {
330
+ window.dialogArguments = vArguments;
331
+ modalWin = window.open(sURL, 'modal', sFeatures);
332
+ return modalWin;
333
+ }
334
+ }
335
+ browser.execute_script script
336
+ yield if block_given?
337
+ end
338
+
339
+ #
340
+ # Attach to a running window. You can locate the window using either
341
+ # the window's title or url. If it fails to connect to a window it will
342
+ # pause for 1 second and try again.
343
+ #
344
+ # @example
345
+ # page.attach_to_window(:title => "other window's title")
346
+ #
347
+ # @param [Hash] either :title or :url of the other window. The url does not need to
348
+ # be the entire url - it can just be the page name like index.html
349
+ # @param block if present the block is executed and then execution is returned to the
350
+ # calling window
351
+ #
352
+ def attach_to_window(identifier, &block)
353
+ begin
354
+ platform.attach_to_window(identifier, &block)
355
+ rescue
356
+ sleep 1
357
+ platform.attach_to_window(identifier, &block)
358
+ end
359
+ end
360
+
361
+ #
362
+ # Find the element that has focus on the page
363
+ #
364
+ def element_with_focus
365
+ platform.element_with_focus
366
+ end
367
+
368
+ #
369
+ # Refresh to current page
370
+ #
371
+ def refresh
372
+ platform.refresh
373
+ end
374
+
375
+ #
376
+ # Go back to the previous page
377
+ #
378
+ def back
379
+ platform.back
380
+ end
381
+
382
+ #
383
+ # Go forward to the next page
384
+ #
385
+ def forward
386
+ platform.forward
387
+ end
388
+
389
+ #
390
+ # Clear the cookies from the browser
391
+ #
392
+ def clear_cookies
393
+ platform.clear_cookies
394
+ end
395
+
396
+ #
397
+ # Save the current screenshot to the provided url. File
398
+ # is saved as a png file.
399
+ #
400
+ def save_screenshot(file_name)
401
+ platform.save_screenshot file_name
402
+ end
403
+
404
+ def self.register_widget(widget_tag, widget_class, base_element_tag)
405
+ Widgets.register_widget(widget_tag, widget_class, base_element_tag)
406
+ end
407
+
408
+ private
409
+
410
+ def root
411
+ @root_element || browser_root_for(browser, PageObject::Platforms.get)
412
+ end
413
+
414
+ def include_platform_driver(browser)
415
+ @platform = load_platform(browser, PageObject::Platforms.get)
416
+ end
417
+
418
+ def call_block(&block)
419
+ block.arity == 1 ? block.call(self) : self.instance_eval(&block)
420
+ end
421
+ end