zena 1.2.7 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (407) hide show
  1. data/History.txt +80 -25
  2. data/Rakefile +2 -2
  3. data/app/controllers/columns_controller.rb +2 -2
  4. data/app/controllers/nodes_controller.rb +22 -29
  5. data/app/controllers/user_sessions_controller.rb +35 -10
  6. data/app/controllers/users_controller.rb +2 -2
  7. data/app/controllers/versions_controller.rb +2 -2
  8. data/app/models/group.rb +15 -1
  9. data/app/models/node.rb +109 -8
  10. data/app/models/role.rb +4 -0
  11. data/app/models/site.rb +64 -58
  12. data/app/models/template.rb +1 -1
  13. data/app/models/user.rb +135 -29
  14. data/app/models/user_session.rb +0 -1
  15. data/app/models/virtual_class.rb +11 -6
  16. data/app/views/columns/_form.html.erb +3 -1
  17. data/app/views/columns/_li.html.erb +1 -1
  18. data/app/views/columns/create.rjs +1 -1
  19. data/app/views/groups/_form.rhtml +16 -13
  20. data/app/views/relations/_form.erb +18 -6
  21. data/app/views/sites/_form.erb +12 -6
  22. data/app/views/users/_form.rhtml +23 -8
  23. data/app/views/users/_li.rhtml +14 -3
  24. data/app/views/users/index.rhtml +1 -1
  25. data/app/views/virtual_classes/_form.erb +12 -2
  26. data/app/views/zafu/default/Node-+login.zafu +8 -1
  27. data/app/views/zafu/default/Node-+search.zafu +1 -1
  28. data/bricks/acls/lib/bricks/acls.rb +1 -0
  29. data/bricks/acls/zena/migrate/20130903150356_longer_names_for_acl.rb +9 -0
  30. data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
  31. data/bricks/currency/lib/bricks/currency.rb +120 -0
  32. data/bricks/currency/zena/test/unit/currency_test.rb +43 -0
  33. data/bricks/fs_skin/lib/bricks/fs_skin.rb +1 -1
  34. data/bricks/fs_skin/zena/skins/blog/Node-+search.zafu +1 -1
  35. data/bricks/fs_skin/zena/skins/blog/Node.zafu +1 -1
  36. data/bricks/fs_skin/zena/test/unit/fs_skin_view_test.rb +35 -0
  37. data/bricks/pdf/lib/bricks/pdf.rb +1 -1
  38. data/bricks/sphinx/lib/bricks/sphinx.rb +2 -0
  39. data/bricks/sphinx/zena/init.rb +14 -0
  40. data/bricks/tags/zena/test/zafu/tags.yml +5 -1
  41. data/bricks/worker/lib/bricks/worker.rb +3 -2
  42. data/bricks/zena/zena/migrate/20130829093753_add_versioned_flag_to_column.rb +10 -0
  43. data/bricks/zena/zena/migrate/20130903084909_count_login_attempts.rb +11 -0
  44. data/bricks/zena/zena/migrate/20131104153126_index_fullpath.rb +10 -0
  45. data/bricks/zena/zena/migrate/20131104210011_rebuild_fullpath_after_change.rb +10 -0
  46. data/bricks/zena/zena/migrate/20131105160420_add_skin_id_to_sites.rb +9 -0
  47. data/bricks/zena/zena/migrate/20131105175822_add_profile_to_users.rb +11 -0
  48. data/bricks/zena/zena/migrate/20140213120038_fix_idx_scope.rb +13 -0
  49. data/bricks/zena/zena/migrate/20140628140247_add_site_readonly.rb +9 -0
  50. data/config/bricks.yml +8 -4
  51. data/config/gems.yml +5 -3
  52. data/db/init/base/skins/default/Node-+login.zafu +8 -1
  53. data/db/init/base/skins/default/Node-+search.zafu +1 -1
  54. data/lib/bricks/loader.rb +5 -5
  55. data/lib/gettext_strings.rb +3 -0
  56. data/lib/tasks/zena.rake +25 -22
  57. data/lib/zafu/process/context.rb +4 -0
  58. data/lib/zena/acts/secure_node.rb +3 -3
  59. data/lib/zena/app.rb +1 -0
  60. data/lib/zena/deploy.rb +1 -1
  61. data/lib/zena/deploy/template.rb +1 -1
  62. data/lib/zena/foxy_parser.rb +5 -2
  63. data/lib/zena/info.rb +1 -1
  64. data/lib/zena/site_worker.rb +2 -2
  65. data/lib/zena/test_controller.rb +5 -2
  66. data/lib/zena/use/action.rb +9 -2
  67. data/lib/zena/use/ajax.rb +20 -4
  68. data/lib/zena/use/ancestry.rb +89 -15
  69. data/lib/zena/use/authlogic.rb +8 -2
  70. data/lib/zena/use/context.rb +1 -0
  71. data/lib/zena/use/display.rb +1 -97
  72. data/lib/zena/use/forms.rb +28 -8
  73. data/lib/zena/use/html_tags.rb +16 -7
  74. data/lib/zena/use/i18n.rb +1 -1
  75. data/lib/zena/use/prop_eval.rb +6 -1
  76. data/lib/zena/use/query_node.rb +69 -4
  77. data/lib/zena/use/recursion.rb +1 -1
  78. data/lib/zena/use/refactor.rb +5 -2
  79. data/lib/zena/use/relations.rb +1 -0
  80. data/lib/zena/use/rendering.rb +7 -4
  81. data/lib/zena/use/test_helper.rb +8 -4
  82. data/lib/zena/use/upload.rb +14 -0
  83. data/lib/zena/use/urls.rb +39 -23
  84. data/lib/zena/use/version_hash.rb +5 -2
  85. data/lib/zena/use/workflow.rb +116 -70
  86. data/lib/zena/use/zafu_eval.rb +41 -0
  87. data/lib/zena/use/zafu_safe_definitions.rb +1 -0
  88. data/lib/zena/use/zafu_templates.rb +32 -26
  89. data/lib/zena/use/zazen.rb +8 -7
  90. data/locale/app.pot +5 -1
  91. data/locale/de/LC_MESSAGES/zena.mo +0 -0
  92. data/locale/de/zena.po +385 -281
  93. data/locale/en/LC_MESSAGES/zena.mo +0 -0
  94. data/locale/en/zena.po +378 -271
  95. data/locale/fr/LC_MESSAGES/zena.mo +0 -0
  96. data/locale/fr/zena.po +387 -272
  97. data/locale/it/LC_MESSAGES/zena.mo +0 -0
  98. data/locale/it/zena.po +433 -404
  99. data/locale/zena.pot +362 -268
  100. data/public/javascripts/grid.js +280 -104
  101. data/public/javascripts/zena.js +43 -15
  102. data/public/stylesheets/admin.css +8 -2
  103. data/public/stylesheets/grid.css +5 -2
  104. data/public/stylesheets/popup.css +1 -1
  105. data/test/fixtures/files/TestNode.zafu +51 -0
  106. data/test/functional/nodes_controller_test.rb +20 -5
  107. data/test/functional/user_sessions_controller_test.rb +41 -6
  108. data/test/functional/users_controller_test.rb +1 -2
  109. data/test/integration/navigation_test.rb +22 -4
  110. data/test/integration/query_node/basic.yml +7 -0
  111. data/test/integration/query_node/complex.yml +1 -1
  112. data/test/integration/query_node/errors.yml +1 -1
  113. data/test/integration/query_node/filters.yml +34 -1
  114. data/test/integration/query_node/relations.yml +6 -13
  115. data/test/integration/query_node_test.rb +22 -3
  116. data/test/integration/zafu_compiler/action.yml +1 -1
  117. data/test/integration/zafu_compiler/alias_site.yml +52 -0
  118. data/test/integration/zafu_compiler/complex.yml +1 -1
  119. data/test/integration/zafu_compiler/complex_ok.yml +5 -5
  120. data/test/integration/zafu_compiler/context.yml +1 -1
  121. data/test/integration/zafu_compiler/display.yml +56 -5
  122. data/test/integration/zafu_compiler/forms.yml +35 -2
  123. data/test/integration/zafu_compiler/meta.yml +4 -0
  124. data/test/integration/zafu_compiler/rubyless.yml +1 -1
  125. data/test/integration/zafu_compiler/safe_definitions.yml +4 -0
  126. data/test/integration/zafu_compiler/security.yml +10 -0
  127. data/test/integration/zafu_compiler/site.yml +5 -1
  128. data/test/integration/zafu_compiler/urls.yml +8 -2
  129. data/test/integration/zafu_compiler/zafu_attributes.yml +2 -1
  130. data/test/integration/zafu_compiler/zazen.yml +4 -0
  131. data/test/integration/zafu_compiler_test.rb +47 -4
  132. data/test/selenium/Grid/grid1.rsel +8 -8
  133. data/test/sites/complex/sites.yml +2 -2
  134. data/test/sites/complex/users.yml +1 -0
  135. data/test/sites/zena/columns.yml +4 -0
  136. data/test/sites/zena/sites.yml +1 -0
  137. data/test/sites/zena/users.yml +1 -0
  138. data/test/unit/node_test.rb +53 -5
  139. data/test/unit/note_test.rb +1 -1
  140. data/test/unit/relation_proxy_test.rb +20 -0
  141. data/test/unit/role_test.rb +2 -0
  142. data/test/unit/site_test.rb +28 -6
  143. data/test/unit/user_test.rb +332 -1
  144. data/test/unit/virtual_class_test.rb +55 -0
  145. data/test/unit/workflow_test.rb +175 -0
  146. data/test/unit/zena/use/ancestry_test.rb +52 -10
  147. data/test/unit/zena/use/prop_eval_test.rb +44 -0
  148. data/test/unit/zena/use/rendering_test.rb +48 -2
  149. data/test/unit/zena/use/upload_test.rb +15 -13
  150. data/test/unit/zena/use/urls_test.rb +1 -0
  151. data/vendor/plugins/ar_mysql_full_text/lib/ar_mysql_full_text.rb +39 -25
  152. data/zena.gemspec +69 -307
  153. metadata +143 -368
  154. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run 2.tmCommand +0 -24
  155. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Context.tmCommand +0 -58
  156. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Focused Should.tmCommand +0 -88
  157. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run.tmCommand +0 -27
  158. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/YAML to Shoulda.tmCommand +0 -23
  159. data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Context.tmPreferences +0 -19
  160. data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Should.tmPreferences +0 -19
  161. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory attributes for.tmSnippet +0 -16
  162. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory build.tmSnippet +0 -16
  163. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory.tmSnippet +0 -16
  164. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define with class.tmSnippet +0 -18
  165. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define.tmSnippet +0 -18
  166. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_next.tmSnippet +0 -16
  167. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_sequence.tmSnippet +0 -18
  168. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_bad_value.tmSnippet +0 -16
  169. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_contains.tmSnippet +0 -16
  170. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_does_not_contain.tmSnippet +0 -16
  171. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_good_value.tmSnippet +0 -16
  172. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_same_elements.tmSnippet +0 -16
  173. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_save.tmSnippet +0 -16
  174. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_sent_email.tmSnippet +0 -18
  175. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_valid.tmSnippet +0 -16
  176. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/association.tmSnippet +0 -17
  177. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/attribute.tmSnippet +0 -17
  178. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/before_should block.tmSnippet +0 -18
  179. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block get.tmSnippet +0 -22
  180. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block post.tmSnippet +0 -23
  181. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block with setup.tmSnippet +0 -25
  182. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/setup.tmSnippet +0 -18
  183. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block with before proc.tmSnippet +0 -18
  184. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block.tmSnippet +0 -18
  185. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_allow_values_for.tmSnippet +0 -16
  186. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_assign_to.tmSnippet +0 -16
  187. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful denied.tmSnippet +0 -20
  188. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful.tmSnippet +0 -20
  189. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_belong_to.tmSnippet +0 -16
  190. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change by.tmSnippet +0 -16
  191. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change from to.tmSnippet +0 -16
  192. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_at_least.tmSnippet +0 -16
  193. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_in_range.tmSnippet +0 -16
  194. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_is.tmSnippet +0 -16
  195. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_value_in_range.tmSnippet +0 -16
  196. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_eventually.tmSnippet +0 -18
  197. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_filter_params.tmSnippet +0 -16
  198. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_and_belong_to_many.tmSnippet +0 -16
  199. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_class_methods.tmSnippet +0 -16
  200. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_column.tmSnippet +0 -16
  201. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_columns.tmSnippet +0 -16
  202. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_index.tmSnippet +0 -16
  203. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_indices.tmSnippet +0 -16
  204. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_instance_methods.tmSnippet +0 -16
  205. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_many.tmSnippet +0 -16
  206. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_named_scope.tmSnippet +0 -16
  207. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_one.tmSnippet +0 -16
  208. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_readonly_attributes.tmSnippet +0 -16
  209. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_mass_assignment_of.tmSnippet +0 -16
  210. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_values_for.tmSnippet +0 -16
  211. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_assign_to.tmSnippet +0 -16
  212. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_change.tmSnippet +0 -16
  213. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_set_the_flash.tmSnippet +0 -16
  214. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_redirect_to.tmSnippet +0 -16
  215. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_a_form.tmSnippet +0 -16
  216. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_template.tmSnippet +0 -16
  217. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_with_layout.tmSnippet +0 -16
  218. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_without_layout.tmSnippet +0 -16
  219. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with.tmSnippet +0 -16
  220. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with_content_type.tmSnippet +0 -16
  221. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_return_from_session.tmSnippet +0 -16
  222. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_route.tmSnippet +0 -16
  223. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_set_the_flash_to.tmSnippet +0 -16
  224. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_acceptance_of.tmSnippet +0 -16
  225. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_numericality_of.tmSnippet +0 -16
  226. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_presence_of.tmSnippet +0 -16
  227. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of with scope.tmSnippet +0 -16
  228. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of.tmSnippet +0 -16
  229. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/catch_exception.rb +0 -39
  230. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/run_script.rb +0 -104
  231. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/stdin_dialog.rb +0 -14
  232. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/test.rb +0 -17
  233. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/todo.txt +0 -13
  234. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/bin/yaml_to_shoulda.rb +0 -25
  235. data/vendor/TextMate/Ruby Shoulda.tmbundle/Syntaxes/Ruby on Rails (Shoulda).tmLanguage +0 -166
  236. data/vendor/TextMate/Ruby Shoulda.tmbundle/info.plist +0 -304
  237. data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +0 -37
  238. data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +0 -52
  239. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +0 -39
  240. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +0 -118
  241. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +0 -14
  242. data/vendor/TextMate/Zena.tmbundle/info.plist +0 -17
  243. data/vendor/plugins/selenium-on-rails/CHANGELOG +0 -125
  244. data/vendor/plugins/selenium-on-rails/LICENSE-2.0.txt +0 -202
  245. data/vendor/plugins/selenium-on-rails/README.md +0 -202
  246. data/vendor/plugins/selenium-on-rails/Rakefile +0 -38
  247. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumController.html +0 -265
  248. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumHelper.html +0 -148
  249. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails.html +0 -126
  250. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/FixtureLoader.html +0 -231
  251. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/PartialsSupport.html +0 -195
  252. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Paths.html +0 -295
  253. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/RSelenese.html +0 -219
  254. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Renderer.html +0 -156
  255. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Selenese.html +0 -179
  256. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/SuiteRenderer.html +0 -223
  257. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilder.html +0 -441
  258. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderAccessors.html +0 -3098
  259. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderActions.html +0 -2080
  260. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserAccessors.html +0 -116
  261. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserActions.html +0 -116
  262. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRailsConfig.html +0 -150
  263. data/vendor/plugins/selenium-on-rails/doc/files/CHANGELOG.html +0 -422
  264. data/vendor/plugins/selenium-on-rails/doc/files/README.html +0 -321
  265. data/vendor/plugins/selenium-on-rails/doc/files/lib/controllers/selenium_controller_rb.html +0 -108
  266. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_helper_rb.html +0 -101
  267. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/acceptance_test_runner_rb.html +0 -222
  268. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/fixture_loader_rb.html +0 -109
  269. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/partials_support_rb.html +0 -111
  270. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/paths_rb.html +0 -101
  271. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/renderer_rb.html +0 -101
  272. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/rselenese_rb.html +0 -118
  273. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/selenese_rb.html +0 -101
  274. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/suite_renderer_rb.html +0 -101
  275. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_accessors_rb.html +0 -114
  276. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_actions_rb.html +0 -113
  277. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_rb.html +0 -120
  278. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_config_rb.html +0 -108
  279. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_rb.html +0 -115
  280. data/vendor/plugins/selenium-on-rails/doc/fr_class_index.html +0 -42
  281. data/vendor/plugins/selenium-on-rails/doc/fr_file_index.html +0 -43
  282. data/vendor/plugins/selenium-on-rails/doc/fr_method_index.html +0 -182
  283. data/vendor/plugins/selenium-on-rails/doc/index.html +0 -24
  284. data/vendor/plugins/selenium-on-rails/doc/rdoc-style.css +0 -208
  285. data/vendor/plugins/selenium-on-rails/generators/selenium/USAGE +0 -19
  286. data/vendor/plugins/selenium-on-rails/generators/selenium/selenium_generator.rb +0 -50
  287. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/rhtml.rhtml +0 -16
  288. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/rselenese.rhtml +0 -14
  289. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/selenese.rhtml +0 -11
  290. data/vendor/plugins/selenium-on-rails/init.rb +0 -15
  291. data/vendor/plugins/selenium-on-rails/lib/controllers/selenium_controller.rb +0 -122
  292. data/vendor/plugins/selenium-on-rails/lib/controllers/switch_environment_controller.rb +0 -16
  293. data/vendor/plugins/selenium-on-rails/lib/selenium_helper.rb +0 -8
  294. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails.rb +0 -11
  295. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/acceptance_test_runner.rb +0 -215
  296. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/fixture_loader.rb +0 -57
  297. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/partials_support.rb +0 -36
  298. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/paths.rb +0 -61
  299. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/renderer.rb +0 -20
  300. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/rselenese.rb +0 -44
  301. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/selenese.rb +0 -87
  302. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/suite_renderer.rb +0 -56
  303. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder.rb +0 -116
  304. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_accessors.rb +0 -1002
  305. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_actions.rb +0 -514
  306. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_accessors.rb.example +0 -91
  307. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_actions.rb.example +0 -24
  308. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb +0 -30
  309. data/vendor/plugins/selenium-on-rails/lib/views/layouts/layout.rhtml +0 -18
  310. data/vendor/plugins/selenium-on-rails/lib/views/record.rhtml +0 -5
  311. data/vendor/plugins/selenium-on-rails/lib/views/selenium_helper.rb +0 -9
  312. data/vendor/plugins/selenium-on-rails/lib/views/setup.rhtml +0 -67
  313. data/vendor/plugins/selenium-on-rails/lib/views/test_suite.rhtml +0 -26
  314. data/vendor/plugins/selenium-on-rails/routes.rb +0 -24
  315. data/vendor/plugins/selenium-on-rails/selenium-core/Blank.html +0 -7
  316. data/vendor/plugins/selenium-on-rails/selenium-core/InjectedRemoteRunner.html +0 -8
  317. data/vendor/plugins/selenium-on-rails/selenium-core/RemoteRunner.html +0 -110
  318. data/vendor/plugins/selenium-on-rails/selenium-core/SeleniumLog.html +0 -109
  319. data/vendor/plugins/selenium-on-rails/selenium-core/TestPrompt.html +0 -145
  320. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner-splash.html +0 -55
  321. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.hta +0 -177
  322. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.html +0 -177
  323. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butmin.gif +0 -0
  324. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butplus.gif +0 -0
  325. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.css +0 -298
  326. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.html +0 -16
  327. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/selenium-domviewer.js +0 -205
  328. data/vendor/plugins/selenium-on-rails/selenium-core/icons/all.png +0 -0
  329. data/vendor/plugins/selenium-on-rails/selenium-core/icons/continue.png +0 -0
  330. data/vendor/plugins/selenium-on-rails/selenium-core/icons/continue_disabled.png +0 -0
  331. data/vendor/plugins/selenium-on-rails/selenium-core/icons/pause.png +0 -0
  332. data/vendor/plugins/selenium-on-rails/selenium-core/icons/pause_disabled.png +0 -0
  333. data/vendor/plugins/selenium-on-rails/selenium-core/icons/selected.png +0 -0
  334. data/vendor/plugins/selenium-on-rails/selenium-core/icons/step.png +0 -0
  335. data/vendor/plugins/selenium-on-rails/selenium-core/icons/step_disabled.png +0 -0
  336. data/vendor/plugins/selenium-on-rails/selenium-core/iedoc-core.xml +0 -1759
  337. data/vendor/plugins/selenium-on-rails/selenium-core/iedoc.xml +0 -1800
  338. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/cssQuery-p.js +0 -6
  339. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level2.js +0 -142
  340. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level3.js +0 -150
  341. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-standard.js +0 -53
  342. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery.js +0 -356
  343. data/vendor/plugins/selenium-on-rails/selenium-core/lib/prototype.js +0 -2006
  344. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/builder.js +0 -101
  345. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/controls.js +0 -815
  346. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/dragdrop.js +0 -915
  347. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/effects.js +0 -958
  348. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/scriptaculous.js +0 -47
  349. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/slider.js +0 -283
  350. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/unittest.js +0 -383
  351. data/vendor/plugins/selenium-on-rails/selenium-core/lib/snapsie.js +0 -91
  352. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/find_matching_child.js +0 -69
  353. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/htmlutils.js +0 -1616
  354. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/injection.html +0 -72
  355. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-api.js +0 -3184
  356. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserbot.js +0 -2300
  357. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserdetect.js +0 -153
  358. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-commandhandlers.js +0 -377
  359. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-executionloop.js +0 -175
  360. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-logging.js +0 -148
  361. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-remoterunner.js +0 -695
  362. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-testrunner.js +0 -1362
  363. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-version.js +0 -5
  364. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-doc.html +0 -803
  365. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-element.js +0 -1537
  366. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-map-sample.js +0 -979
  367. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js +0 -3
  368. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js.sample +0 -75
  369. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/xmlextras.js +0 -153
  370. data/vendor/plugins/selenium-on-rails/selenium-core/selenium-logo.png +0 -0
  371. data/vendor/plugins/selenium-on-rails/selenium-core/selenium-test.css +0 -43
  372. data/vendor/plugins/selenium-on-rails/selenium-core/selenium.css +0 -316
  373. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/dom.js +0 -566
  374. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/javascript-xpath-0.1.11.js +0 -2816
  375. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/util.js +0 -549
  376. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/xmltoken.js +0 -149
  377. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/xpath.js +0 -2450
  378. data/vendor/plugins/selenium-on-rails/tasks/test_acceptance.rake +0 -8
  379. data/vendor/plugins/selenium-on-rails/test/fixtures/config.yml +0 -37
  380. data/vendor/plugins/selenium-on-rails/test/fixtures/selenium.yml +0 -27
  381. data/vendor/plugins/selenium-on-rails/test/paths_test.rb +0 -72
  382. data/vendor/plugins/selenium-on-rails/test/renderer_test.rb +0 -157
  383. data/vendor/plugins/selenium-on-rails/test/rselenese_test.rb +0 -708
  384. data/vendor/plugins/selenium-on-rails/test/selenese_test.rb +0 -242
  385. data/vendor/plugins/selenium-on-rails/test/selenium_controller_test.rb +0 -67
  386. data/vendor/plugins/selenium-on-rails/test/selenium_on_rails_config_test.rb +0 -43
  387. data/vendor/plugins/selenium-on-rails/test/selenium_support_test.rb +0 -35
  388. data/vendor/plugins/selenium-on-rails/test/setup_test.rb +0 -31
  389. data/vendor/plugins/selenium-on-rails/test/suite_renderer_test.rb +0 -109
  390. data/vendor/plugins/selenium-on-rails/test/switch_environment_controller_test.rb +0 -17
  391. data/vendor/plugins/selenium-on-rails/test/test_builder_functions_authortest.rb +0 -51
  392. data/vendor/plugins/selenium-on-rails/test/test_helper.rb +0 -101
  393. data/vendor/plugins/selenium-on-rails/test_data/_partial.rsel +0 -1
  394. data/vendor/plugins/selenium-on-rails/test_data/own_layout.html +0 -12
  395. data/vendor/plugins/selenium-on-rails/test_data/partials/_html.html +0 -6
  396. data/vendor/plugins/selenium-on-rails/test_data/partials/_nesting.rsel +0 -2
  397. data/vendor/plugins/selenium-on-rails/test_data/partials/_rhtml.rhtml +0 -6
  398. data/vendor/plugins/selenium-on-rails/test_data/partials/_rsel.rsel +0 -1
  399. data/vendor/plugins/selenium-on-rails/test_data/partials/_sel.sel +0 -5
  400. data/vendor/plugins/selenium-on-rails/test_data/partials/all_partials.rsel +0 -5
  401. data/vendor/plugins/selenium-on-rails/test_data/rhtml.rhtml +0 -7
  402. data/vendor/plugins/selenium-on-rails/test_data/rselenese.rsel +0 -8
  403. data/vendor/plugins/selenium-on-rails/test_data/selenese.sel +0 -7
  404. data/vendor/plugins/selenium-on-rails/test_data/suite_one/subsuite/suite_one_subsuite_testcase.sel +0 -1
  405. data/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase1.sel +0 -1
  406. data/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase2.sel +0 -1
  407. data/vendor/plugins/selenium-on-rails/test_data/suite_two/suite_two_testcase.sel +0 -1
@@ -1,72 +0,0 @@
1
- <script language="JavaScript">
2
- if (window["selenium_has_been_loaded_into_this_window"]==null)
3
- {
4
-
5
- __SELENIUM_JS__
6
- // Some background on the code below: broadly speaking, where we are relative to other windows
7
- // when running in proxy injection mode depends on whether we are in a frame set file or not.
8
- //
9
- // In regular HTML files, the selenium JavaScript is injected into an iframe called "selenium"
10
- // in order to reduce its impact on the JavaScript environment (through namespace pollution,
11
- // etc.). So in regular HTML files, we need to look at the parent of the current window when we want
12
- // a handle to, e.g., the application window.
13
- //
14
- // In frame set files, we can't use an iframe, so we put the JavaScript in the head element and share
15
- // the window with the frame set. So in this case, we need to look at the current window, not the
16
- // parent when looking for, e.g., the application window. (TODO: Perhaps I should have just
17
- // assigned a regular frame for selenium?)
18
- //
19
- BrowserBot.prototype.getContentWindow = function() {
20
- return window;
21
- };
22
-
23
- BrowserBot.prototype.getTargetWindow = function(windowName) {
24
- return window;
25
- };
26
-
27
- BrowserBot.prototype.getCurrentWindow = function() {
28
- return window;
29
- };
30
-
31
- LOG.openLogWindow = function(message, className) {
32
- // disable for now
33
- };
34
-
35
- BrowserBot.prototype.relayToRC = function(name) {
36
- var object = eval(name);
37
- var s = 'state:' + serializeObject(name, object) + "\n";
38
- sendToRC(s,"state=true");
39
- }
40
-
41
- function selenium_frameRunTest(oldOnLoadRoutine) {
42
- if (oldOnLoadRoutine) {
43
- eval(oldOnLoadRoutine);
44
- }
45
- runSeleniumTest();
46
- }
47
-
48
- function seleniumOnLoad() {
49
- injectedSessionId = "@SESSION_ID@";
50
- window["selenium_has_been_loaded_into_this_window"] = true;
51
- runSeleniumTest();
52
- }
53
-
54
- function seleniumOnUnload() {
55
- sendToRC("Current window or frame is closed!", "closing=true");
56
- }
57
-
58
- if (window.addEventListener) {
59
- window.addEventListener("load", seleniumOnLoad, false); // firefox
60
- window.addEventListener("unload", seleniumOnUnload, false); // firefox
61
- } else if (window.attachEvent){
62
- window.attachEvent("onload", seleniumOnLoad); // IE
63
- window.attachEvent("onunload", seleniumOnUnload); // IE
64
- }
65
- else {
66
- throw "causing a JavaScript error to tell the world that I did not arrange to be run on load";
67
- }
68
-
69
- injectedSessionId = "@SESSION_ID@";
70
- proxyInjectionMode = true;
71
- }
72
- </script>
@@ -1,3184 +0,0 @@
1
- /*
2
- * Copyright 2004 ThoughtWorks, Inc
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- *
16
- */
17
-
18
- // TODO: stop navigating this.browserbot.document() ... it breaks encapsulation
19
-
20
- var storedVars = new Object();
21
-
22
- function Selenium(browserbot) {
23
- /**
24
- * Defines an object that runs Selenium commands.
25
- *
26
- * <h3><a name="locators"></a>Element Locators</h3>
27
- * <p>
28
- * Element Locators tell Selenium which HTML element a command refers to.
29
- * The format of a locator is:</p>
30
- * <blockquote>
31
- * <em>locatorType</em><strong>=</strong><em>argument</em>
32
- * </blockquote>
33
- *
34
- * <p>
35
- * We support the following strategies for locating elements:
36
- * </p>
37
- *
38
- * <ul>
39
- * <li><strong>identifier</strong>=<em>id</em>:
40
- * Select the element with the specified &#064;id attribute. If no match is
41
- * found, select the first element whose &#064;name attribute is <em>id</em>.
42
- * (This is normally the default; see below.)</li>
43
- * <li><strong>id</strong>=<em>id</em>:
44
- * Select the element with the specified &#064;id attribute.</li>
45
- *
46
- * <li><strong>name</strong>=<em>name</em>:
47
- * Select the first element with the specified &#064;name attribute.
48
- * <ul class="first last simple">
49
- * <li>username</li>
50
- * <li>name=username</li>
51
- * </ul>
52
- *
53
- * <p>The name may optionally be followed by one or more <em>element-filters</em>, separated from the name by whitespace. If the <em>filterType</em> is not specified, <strong>value</strong> is assumed.</p>
54
- *
55
- * <ul class="first last simple">
56
- * <li>name=flavour value=chocolate</li>
57
- * </ul>
58
- * </li>
59
- * <li><strong>dom</strong>=<em>javascriptExpression</em>:
60
- *
61
- * Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object
62
- * Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block.
63
- * <ul class="first last simple">
64
- * <li>dom=document.forms['myForm'].myDropdown</li>
65
- * <li>dom=document.images[56]</li>
66
- * <li>dom=function foo() { return document.links[1]; }; foo();</li>
67
- * </ul>
68
- *
69
- * </li>
70
- *
71
- * <li><strong>xpath</strong>=<em>xpathExpression</em>:
72
- * Locate an element using an XPath expression.
73
- * <ul class="first last simple">
74
- * <li>xpath=//img[&#064;alt='The image alt text']</li>
75
- * <li>xpath=//table[&#064;id='table1']//tr[4]/td[2]</li>
76
- * <li>xpath=//a[contains(&#064;href,'#id1')]</li>
77
- * <li>xpath=//a[contains(&#064;href,'#id1')]/&#064;class</li>
78
- * <li>xpath=(//table[&#064;class='stylee'])//th[text()='theHeaderText']/../td</li>
79
- * <li>xpath=//input[&#064;name='name2' and &#064;value='yes']</li>
80
- * <li>xpath=//*[text()="right"]</li>
81
- *
82
- * </ul>
83
- * </li>
84
- * <li><strong>link</strong>=<em>textPattern</em>:
85
- * Select the link (anchor) element which contains text matching the
86
- * specified <em>pattern</em>.
87
- * <ul class="first last simple">
88
- * <li>link=The link text</li>
89
- * </ul>
90
- *
91
- * </li>
92
- *
93
- * <li><strong>css</strong>=<em>cssSelectorSyntax</em>:
94
- * Select the element using css selectors. Please refer to <a href="http://www.w3.org/TR/REC-CSS2/selector.html">CSS2 selectors</a>, <a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">CSS3 selectors</a> for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package.
95
- * <ul class="first last simple">
96
- * <li>css=a[href="#id3"]</li>
97
- * <li>css=span#firstChild + span</li>
98
- * </ul>
99
- * <p>Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after). </p>
100
- * </li>
101
- *
102
- * <li><strong>ui</strong>=<em>uiSpecifierString</em>:
103
- * Locate an element by resolving the UI specifier string to another locator, and evaluating it. See the <a href="http://svn.openqa.org/fisheye/browse/~raw,r=trunk/selenium/trunk/src/main/resources/core/scripts/ui-doc.html">Selenium UI-Element Reference</a> for more details.
104
- * <ul class="first last simple">
105
- * <li>ui=loginPages::loginButton()</li>
106
- * <li>ui=settingsPages::toggle(label=Hide Email)</li>
107
- * <li>ui=forumPages::postBody(index=2)//a[2]</li>
108
- * </ul>
109
- * </li>
110
- *
111
- * </ul>
112
- *
113
- * <p>
114
- * Without an explicit locator prefix, Selenium uses the following default
115
- * strategies:
116
- * </p>
117
- *
118
- * <ul class="simple">
119
- * <li><strong>dom</strong>, for locators starting with &quot;document.&quot;</li>
120
- * <li><strong>xpath</strong>, for locators starting with &quot;//&quot;</li>
121
- * <li><strong>identifier</strong>, otherwise</li>
122
- * </ul>
123
- *
124
- * <h3><a name="element-filters">Element Filters</a></h3>
125
- * <blockquote>
126
- * <p>Element filters can be used with a locator to refine a list of candidate elements. They are currently used only in the 'name' element-locator.</p>
127
- * <p>Filters look much like locators, ie.</p>
128
- * <blockquote>
129
- * <em>filterType</em><strong>=</strong><em>argument</em></blockquote>
130
- *
131
- * <p>Supported element-filters are:</p>
132
- * <p><strong>value=</strong><em>valuePattern</em></p>
133
- * <blockquote>
134
- * Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.</blockquote>
135
- * <p><strong>index=</strong><em>index</em></p>
136
- * <blockquote>
137
- * Selects a single element based on its position in the list (offset from zero).</blockquote>
138
- * </blockquote>
139
- *
140
- * <h3><a name="patterns"></a>String-match Patterns</h3>
141
- *
142
- * <p>
143
- * Various Pattern syntaxes are available for matching string values:
144
- * </p>
145
- * <ul>
146
- * <li><strong>glob:</strong><em>pattern</em>:
147
- * Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a
148
- * kind of limited regular-expression syntax typically used in command-line
149
- * shells. In a glob pattern, "*" represents any sequence of characters, and "?"
150
- * represents any single character. Glob patterns match against the entire
151
- * string.</li>
152
- * <li><strong>regexp:</strong><em>regexp</em>:
153
- * Match a string using a regular-expression. The full power of JavaScript
154
- * regular-expressions is available.</li>
155
- * <li><strong>regexpi:</strong><em>regexpi</em>:
156
- * Match a string using a case-insensitive regular-expression.</li>
157
- * <li><strong>exact:</strong><em>string</em>:
158
- *
159
- * Match a string exactly, verbatim, without any of that fancy wildcard
160
- * stuff.</li>
161
- * </ul>
162
- * <p>
163
- * If no pattern prefix is specified, Selenium assumes that it's a "glob"
164
- * pattern.
165
- * </p>
166
- * <p>
167
- * For commands that return multiple values (such as verifySelectOptions),
168
- * the string being matched is a comma-separated list of the return values,
169
- * where both commas and backslashes in the values are backslash-escaped.
170
- * When providing a pattern, the optional matching syntax (i.e. glob,
171
- * regexp, etc.) is specified once, as usual, at the beginning of the
172
- * pattern.
173
- * </p>
174
- */
175
- this.browserbot = browserbot;
176
- this.optionLocatorFactory = new OptionLocatorFactory();
177
- // DGF for backwards compatibility
178
- this.page = function() {
179
- return browserbot;
180
- };
181
- this.defaultTimeout = Selenium.DEFAULT_TIMEOUT;
182
- this.mouseSpeed = 10;
183
- }
184
-
185
- Selenium.DEFAULT_TIMEOUT = 30 * 1000;
186
- Selenium.DEFAULT_MOUSE_SPEED = 10;
187
- Selenium.RIGHT_MOUSE_CLICK = 2;
188
-
189
- Selenium.decorateFunctionWithTimeout = function(f, timeout) {
190
- if (f == null) {
191
- return null;
192
- }
193
-
194
- var timeoutTime = getTimeoutTime(timeout);
195
-
196
- return function() {
197
- if (new Date().getTime() > timeoutTime) {
198
- throw new SeleniumError("Timed out after " + timeout + "ms");
199
- }
200
- return f();
201
- };
202
- }
203
-
204
- Selenium.createForWindow = function(window, proxyInjectionMode) {
205
- if (!window.location) {
206
- throw "error: not a window!";
207
- }
208
- return new Selenium(BrowserBot.createForWindow(window, proxyInjectionMode));
209
- };
210
-
211
- Selenium.prototype.reset = function() {
212
- this.defaultTimeout = Selenium.DEFAULT_TIMEOUT;
213
- // todo: this.browserbot.reset()
214
- this.browserbot.selectWindow("null");
215
- this.browserbot.resetPopups();
216
- };
217
-
218
- Selenium.prototype.doClick = function(locator) {
219
- /**
220
- * Clicks on a link, button, checkbox or radio button. If the click action
221
- * causes a new page to load (like a link usually does), call
222
- * waitForPageToLoad.
223
- *
224
- * @param locator an element locator
225
- *
226
- */
227
- var element = this.browserbot.findElement(locator);
228
- var elementWithHref = getAncestorOrSelfWithJavascriptHref(element);
229
-
230
- if (browserVersion.isChrome && elementWithHref != null) {
231
- // SEL-621: Firefox chrome: Race condition bug in alert-handling code
232
- //
233
- // This appears to be because javascript href's are being executed in a
234
- // separate thread from the main thread when running in chrome mode.
235
- //
236
- // This workaround injects a callback into the executing href that
237
- // lowers a flag, which is initially raised. Execution of this click
238
- // command will wait for the flag to be lowered.
239
-
240
- var win = elementWithHref.ownerDocument.defaultView;
241
- var originalLocation = win.location.href;
242
- var originalHref = elementWithHref.href;
243
-
244
- elementWithHref.href = 'javascript:try { '
245
- + originalHref.replace(/^\s*javascript:/i, "")
246
- + '} finally { window._executingJavascriptHref = undefined; }' ;
247
-
248
- win._executingJavascriptHref = true;
249
-
250
- this.browserbot.clickElement(element);
251
-
252
- return Selenium.decorateFunctionWithTimeout(function() {
253
- if (win.closed) {
254
- return true;
255
- }
256
- if (win.location.href != originalLocation) {
257
- // navigated to some other page ... javascript from previous
258
- // page can't still be executing!
259
- return true;
260
- }
261
- if (! win._executingJavascriptHref) {
262
- try {
263
- elementWithHref.href = originalHref;
264
- }
265
- catch (e) {
266
- // maybe the javascript removed the element ... should be
267
- // no danger in not reverting its href attribute
268
- }
269
- return true;
270
- }
271
-
272
- return false;
273
- }, Selenium.DEFAULT_TIMEOUT);
274
- }
275
-
276
- this.browserbot.clickElement(element);
277
- };
278
-
279
- Selenium.prototype.doDoubleClick = function(locator) {
280
- /**
281
- * Double clicks on a link, button, checkbox or radio button. If the double click action
282
- * causes a new page to load (like a link usually does), call
283
- * waitForPageToLoad.
284
- *
285
- * @param locator an element locator
286
- *
287
- */
288
- var element = this.browserbot.findElement(locator);
289
- this.browserbot.doubleClickElement(element);
290
- };
291
-
292
- Selenium.prototype.doContextMenu = function(locator) {
293
- /**
294
- * Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element).
295
- *
296
- * @param locator an element locator
297
- *
298
- */
299
- var element = this.browserbot.findElement(locator);
300
- this.browserbot.contextMenuOnElement(element);
301
- };
302
-
303
- Selenium.prototype.doClickAt = function(locator, coordString) {
304
- /**
305
- * Clicks on a link, button, checkbox or radio button. If the click action
306
- * causes a new page to load (like a link usually does), call
307
- * waitForPageToLoad.
308
- *
309
- * @param locator an element locator
310
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
311
- * event relative to the element returned by the locator.
312
- *
313
- */
314
- var element = this.browserbot.findElement(locator);
315
- var clientXY = getClientXY(element, coordString)
316
- this.doMouseMove(locator);
317
- this.doMouseDown(locator);
318
- this.browserbot.clickElement(element, clientXY[0], clientXY[1]);
319
- this.doMouseUp(locator);
320
- };
321
-
322
- Selenium.prototype.doDoubleClickAt = function(locator, coordString) {
323
- /**
324
- * Doubleclicks on a link, button, checkbox or radio button. If the action
325
- * causes a new page to load (like a link usually does), call
326
- * waitForPageToLoad.
327
- *
328
- * @param locator an element locator
329
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
330
- * event relative to the element returned by the locator.
331
- *
332
- */
333
- var element = this.browserbot.findElement(locator);
334
- var clientXY = getClientXY(element, coordString)
335
- this.doMouseMove(locator);
336
- this.doMouseDown(locator);
337
- this.browserbot.doubleClickElement(element, clientXY[0], clientXY[1]);
338
- this.doMouseUp(locator);
339
- };
340
-
341
- Selenium.prototype.doContextMenuAt = function(locator, coordString) {
342
- /**
343
- * Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element).
344
- *
345
- * @param locator an element locator
346
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
347
- * event relative to the element returned by the locator.
348
- *
349
- */
350
- var element = this.browserbot.findElement(locator);
351
- var clientXY = getClientXY(element, coordString)
352
- this.browserbot.contextMenuOnElement(element, clientXY[0], clientXY[1]);
353
- };
354
-
355
- Selenium.prototype.doFireEvent = function(locator, eventName) {
356
- /**
357
- * Explicitly simulate an event, to trigger the corresponding &quot;on<em>event</em>&quot;
358
- * handler.
359
- *
360
- * @param locator an <a href="#locators">element locator</a>
361
- * @param eventName the event name, e.g. "focus" or "blur"
362
- */
363
- var element = this.browserbot.findElement(locator);
364
- triggerEvent(element, eventName, false);
365
- };
366
-
367
- Selenium.prototype.doFocus = function(locator) {
368
- /** Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field.
369
- *
370
- * @param locator an <a href="#locators">element locator</a>
371
- */
372
- var element = this.browserbot.findElement(locator);
373
- if (element.focus) {
374
- element.focus();
375
- } else {
376
- triggerEvent(element, "focus", false);
377
- }
378
- }
379
-
380
- Selenium.prototype.doKeyPress = function(locator, keySequence) {
381
- /**
382
- * Simulates a user pressing and releasing a key.
383
- *
384
- * @param locator an <a href="#locators">element locator</a>
385
- * @param keySequence Either be a string("\" followed by the numeric keycode
386
- * of the key to be pressed, normally the ASCII value of that key), or a single
387
- * character. For example: "w", "\119".
388
- */
389
- var element = this.browserbot.findElement(locator);
390
- triggerKeyEvent(element, 'keypress', keySequence, true,
391
- this.browserbot.controlKeyDown,
392
- this.browserbot.altKeyDown,
393
- this.browserbot.shiftKeyDown,
394
- this.browserbot.metaKeyDown);
395
- };
396
-
397
- Selenium.prototype.doShiftKeyDown = function() {
398
- /**
399
- * Press the shift key and hold it down until doShiftUp() is called or a new page is loaded.
400
- *
401
- */
402
- this.browserbot.shiftKeyDown = true;
403
- };
404
-
405
- Selenium.prototype.doShiftKeyUp = function() {
406
- /**
407
- * Release the shift key.
408
- *
409
- */
410
- this.browserbot.shiftKeyDown = false;
411
- };
412
-
413
- Selenium.prototype.doMetaKeyDown = function() {
414
- /**
415
- * Press the meta key and hold it down until doMetaUp() is called or a new page is loaded.
416
- *
417
- */
418
- this.browserbot.metaKeyDown = true;
419
- };
420
-
421
- Selenium.prototype.doMetaKeyUp = function() {
422
- /**
423
- * Release the meta key.
424
- *
425
- */
426
- this.browserbot.metaKeyDown = false;
427
- };
428
-
429
- Selenium.prototype.doAltKeyDown = function() {
430
- /**
431
- * Press the alt key and hold it down until doAltUp() is called or a new page is loaded.
432
- *
433
- */
434
- this.browserbot.altKeyDown = true;
435
- };
436
-
437
- Selenium.prototype.doAltKeyUp = function() {
438
- /**
439
- * Release the alt key.
440
- *
441
- */
442
- this.browserbot.altKeyDown = false;
443
- };
444
-
445
- Selenium.prototype.doControlKeyDown = function() {
446
- /**
447
- * Press the control key and hold it down until doControlUp() is called or a new page is loaded.
448
- *
449
- */
450
- this.browserbot.controlKeyDown = true;
451
- };
452
-
453
- Selenium.prototype.doControlKeyUp = function() {
454
- /**
455
- * Release the control key.
456
- *
457
- */
458
- this.browserbot.controlKeyDown = false;
459
- };
460
-
461
- Selenium.prototype.doKeyDown = function(locator, keySequence) {
462
- /**
463
- * Simulates a user pressing a key (without releasing it yet).
464
- *
465
- * @param locator an <a href="#locators">element locator</a>
466
- * @param keySequence Either be a string("\" followed by the numeric keycode
467
- * of the key to be pressed, normally the ASCII value of that key), or a single
468
- * character. For example: "w", "\119".
469
- */
470
- var element = this.browserbot.findElement(locator);
471
- triggerKeyEvent(element, 'keydown', keySequence, true,
472
- this.browserbot.controlKeyDown,
473
- this.browserbot.altKeyDown,
474
- this.browserbot.shiftKeyDown,
475
- this.browserbot.metaKeyDown);
476
- };
477
-
478
- Selenium.prototype.doKeyUp = function(locator, keySequence) {
479
- /**
480
- * Simulates a user releasing a key.
481
- *
482
- * @param locator an <a href="#locators">element locator</a>
483
- * @param keySequence Either be a string("\" followed by the numeric keycode
484
- * of the key to be pressed, normally the ASCII value of that key), or a single
485
- * character. For example: "w", "\119".
486
- */
487
- var element = this.browserbot.findElement(locator);
488
- triggerKeyEvent(element, 'keyup', keySequence, true,
489
- this.browserbot.controlKeyDown,
490
- this.browserbot.altKeyDown,
491
- this.browserbot.shiftKeyDown,
492
- this.browserbot.metaKeyDown);
493
- };
494
-
495
- function getClientXY(element, coordString) {
496
- // Parse coordString
497
- var coords = null;
498
- var x;
499
- var y;
500
- if (coordString) {
501
- coords = coordString.split(/,/);
502
- x = Number(coords[0]);
503
- y = Number(coords[1]);
504
- }
505
- else {
506
- x = y = 0;
507
- }
508
-
509
- // Get position of element,
510
- // Return 2 item array with clientX and clientY
511
- return [Selenium.prototype.getElementPositionLeft(element) + x, Selenium.prototype.getElementPositionTop(element) + y];
512
- }
513
-
514
- Selenium.prototype.doMouseOver = function(locator) {
515
- /**
516
- * Simulates a user hovering a mouse over the specified element.
517
- *
518
- * @param locator an <a href="#locators">element locator</a>
519
- */
520
- var element = this.browserbot.findElement(locator);
521
- this.browserbot.triggerMouseEvent(element, 'mouseover', true);
522
- };
523
-
524
- Selenium.prototype.doMouseOut = function(locator) {
525
- /**
526
- * Simulates a user moving the mouse pointer away from the specified element.
527
- *
528
- * @param locator an <a href="#locators">element locator</a>
529
- */
530
- var element = this.browserbot.findElement(locator);
531
- this.browserbot.triggerMouseEvent(element, 'mouseout', true);
532
- };
533
-
534
- Selenium.prototype.doMouseDown = function(locator) {
535
- /**
536
- * Simulates a user pressing the left mouse button (without releasing it yet) on
537
- * the specified element.
538
- *
539
- * @param locator an <a href="#locators">element locator</a>
540
- */
541
- var element = this.browserbot.findElement(locator);
542
- this.browserbot.triggerMouseEvent(element, 'mousedown', true);
543
- };
544
-
545
- Selenium.prototype.doMouseDownRight = function(locator) {
546
- /**
547
- * Simulates a user pressing the right mouse button (without releasing it yet) on
548
- * the specified element.
549
- *
550
- * @param locator an <a href="#locators">element locator</a>
551
- */
552
- var element = this.browserbot.findElement(locator);
553
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, undefined, undefined, Selenium.RIGHT_MOUSE_CLICK);
554
- };
555
-
556
- Selenium.prototype.doMouseDownAt = function(locator, coordString) {
557
- /**
558
- * Simulates a user pressing the left mouse button (without releasing it yet) at
559
- * the specified location.
560
- *
561
- * @param locator an <a href="#locators">element locator</a>
562
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
563
- * event relative to the element returned by the locator.
564
- */
565
- var element = this.browserbot.findElement(locator);
566
- var clientXY = getClientXY(element, coordString)
567
-
568
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientXY[0], clientXY[1]);
569
- };
570
-
571
- Selenium.prototype.doMouseDownRightAt = function(locator, coordString) {
572
- /**
573
- * Simulates a user pressing the right mouse button (without releasing it yet) at
574
- * the specified location.
575
- *
576
- * @param locator an <a href="#locators">element locator</a>
577
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
578
- * event relative to the element returned by the locator.
579
- */
580
- var element = this.browserbot.findElement(locator);
581
- var clientXY = getClientXY(element, coordString)
582
-
583
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientXY[0], clientXY[1], Selenium.RIGHT_MOUSE_CLICK);
584
- };
585
-
586
- Selenium.prototype.doMouseUp = function(locator) {
587
- /**
588
- * Simulates the event that occurs when the user releases the mouse button (i.e., stops
589
- * holding the button down) on the specified element.
590
- *
591
- * @param locator an <a href="#locators">element locator</a>
592
- */
593
- var element = this.browserbot.findElement(locator);
594
- this.browserbot.triggerMouseEvent(element, 'mouseup', true);
595
- };
596
-
597
- Selenium.prototype.doMouseUpRight = function(locator) {
598
- /**
599
- * Simulates the event that occurs when the user releases the right mouse button (i.e., stops
600
- * holding the button down) on the specified element.
601
- *
602
- * @param locator an <a href="#locators">element locator</a>
603
- */
604
- var element = this.browserbot.findElement(locator);
605
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, undefined, undefined, Selenium.RIGHT_MOUSE_CLICK);
606
- };
607
-
608
- Selenium.prototype.doMouseUpAt = function(locator, coordString) {
609
- /**
610
- * Simulates the event that occurs when the user releases the mouse button (i.e., stops
611
- * holding the button down) at the specified location.
612
- *
613
- * @param locator an <a href="#locators">element locator</a>
614
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
615
- * event relative to the element returned by the locator.
616
- */
617
- var element = this.browserbot.findElement(locator);
618
- var clientXY = getClientXY(element, coordString)
619
-
620
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientXY[0], clientXY[1]);
621
- };
622
-
623
- Selenium.prototype.doMouseUpRightAt = function(locator, coordString) {
624
- /**
625
- * Simulates the event that occurs when the user releases the right mouse button (i.e., stops
626
- * holding the button down) at the specified location.
627
- *
628
- * @param locator an <a href="#locators">element locator</a>
629
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
630
- * event relative to the element returned by the locator.
631
- */
632
- var element = this.browserbot.findElement(locator);
633
- var clientXY = getClientXY(element, coordString)
634
-
635
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientXY[0], clientXY[1], Selenium.RIGHT_MOUSE_CLICK);
636
- };
637
-
638
- Selenium.prototype.doMouseMove = function(locator) {
639
- /**
640
- * Simulates a user pressing the mouse button (without releasing it yet) on
641
- * the specified element.
642
- *
643
- * @param locator an <a href="#locators">element locator</a>
644
- */
645
- var element = this.browserbot.findElement(locator);
646
- this.browserbot.triggerMouseEvent(element, 'mousemove', true);
647
- };
648
-
649
- Selenium.prototype.doMouseMoveAt = function(locator, coordString) {
650
- /**
651
- * Simulates a user pressing the mouse button (without releasing it yet) on
652
- * the specified element.
653
- *
654
- * @param locator an <a href="#locators">element locator</a>
655
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
656
- * event relative to the element returned by the locator.
657
- */
658
-
659
- var element = this.browserbot.findElement(locator);
660
- var clientXY = getClientXY(element, coordString)
661
-
662
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientXY[0], clientXY[1]);
663
- };
664
-
665
- Selenium.prototype.doType = function(locator, value) {
666
- /**
667
- * Sets the value of an input field, as though you typed it in.
668
- *
669
- * <p>Can also be used to set the value of combo boxes, check boxes, etc. In these cases,
670
- * value should be the value of the option selected, not the visible text.</p>
671
- *
672
- * @param locator an <a href="#locators">element locator</a>
673
- * @param value the value to type
674
- */
675
- if (this.browserbot.controlKeyDown || this.browserbot.altKeyDown || this.browserbot.metaKeyDown) {
676
- throw new SeleniumError("type not supported immediately after call to controlKeyDown() or altKeyDown() or metaKeyDown()");
677
- }
678
- // TODO fail if it can't be typed into.
679
- var element = this.browserbot.findElement(locator);
680
- if (this.browserbot.shiftKeyDown) {
681
- value = new String(value).toUpperCase();
682
- }
683
- this.browserbot.replaceText(element, value);
684
- };
685
-
686
- Selenium.prototype.doTypeKeys = function(locator, value) {
687
- /**
688
- * Simulates keystroke events on the specified element, as though you typed the value key-by-key.
689
- *
690
- * <p>This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string;
691
- * this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.</p>
692
- *
693
- * <p>Unlike the simple "type" command, which forces the specified value into the page directly, this command
694
- * may or may not have any visible effect, even in cases where typing keys would normally have a visible effect.
695
- * For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in
696
- * the field.</p>
697
- * <p>In some cases, you may need to use the simple "type" command to set the value of the field and then the "typeKeys" command to
698
- * send the keystroke events corresponding to what you just typed.</p>
699
- *
700
- * @param locator an <a href="#locators">element locator</a>
701
- * @param value the value to type
702
- */
703
- var keys = new String(value).split("");
704
- for (var i = 0; i < keys.length; i++) {
705
- var c = keys[i];
706
- this.doKeyDown(locator, c);
707
- this.doKeyUp(locator, c);
708
- this.doKeyPress(locator, c);
709
- }
710
- };
711
-
712
- Selenium.prototype.doSetSpeed = function(value) {
713
- /**
714
- * Set execution speed (i.e., set the millisecond length of a delay which will follow each selenium operation). By default, there is no such delay, i.e.,
715
- * the delay is 0 milliseconds.
716
- *
717
- * @param value the number of milliseconds to pause after operation
718
- */
719
- throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire");
720
- };
721
-
722
- Selenium.prototype.getSpeed = function() {
723
- /**
724
- * Get execution speed (i.e., get the millisecond length of the delay following each selenium operation). By default, there is no such delay, i.e.,
725
- * the delay is 0 milliseconds.
726
- *
727
- * See also setSpeed.
728
- *
729
- * @return string the execution speed in milliseconds.
730
- */
731
- throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire");
732
- };
733
-
734
- Selenium.prototype.findToggleButton = function(locator) {
735
- var element = this.browserbot.findElement(locator);
736
- if (element.checked == null) {
737
- Assert.fail("Element " + locator + " is not a toggle-button.");
738
- }
739
- return element;
740
- }
741
-
742
- Selenium.prototype.doCheck = function(locator) {
743
- /**
744
- * Check a toggle-button (checkbox/radio)
745
- *
746
- * @param locator an <a href="#locators">element locator</a>
747
- */
748
- this.findToggleButton(locator).checked = true;
749
- };
750
-
751
- Selenium.prototype.doUncheck = function(locator) {
752
- /**
753
- * Uncheck a toggle-button (checkbox/radio)
754
- *
755
- * @param locator an <a href="#locators">element locator</a>
756
- */
757
- this.findToggleButton(locator).checked = false;
758
- };
759
-
760
- Selenium.prototype.doSelect = function(selectLocator, optionLocator) {
761
- /**
762
- * Select an option from a drop-down using an option locator.
763
- *
764
- * <p>
765
- * Option locators provide different ways of specifying options of an HTML
766
- * Select element (e.g. for selecting a specific option, or for asserting
767
- * that the selected option satisfies a specification). There are several
768
- * forms of Select Option Locator.
769
- * </p>
770
- * <ul>
771
- * <li><strong>label</strong>=<em>labelPattern</em>:
772
- * matches options based on their labels, i.e. the visible text. (This
773
- * is the default.)
774
- * <ul class="first last simple">
775
- * <li>label=regexp:^[Oo]ther</li>
776
- * </ul>
777
- * </li>
778
- * <li><strong>value</strong>=<em>valuePattern</em>:
779
- * matches options based on their values.
780
- * <ul class="first last simple">
781
- * <li>value=other</li>
782
- * </ul>
783
- *
784
- *
785
- * </li>
786
- * <li><strong>id</strong>=<em>id</em>:
787
- *
788
- * matches options based on their ids.
789
- * <ul class="first last simple">
790
- * <li>id=option1</li>
791
- * </ul>
792
- * </li>
793
- * <li><strong>index</strong>=<em>index</em>:
794
- * matches an option based on its index (offset from zero).
795
- * <ul class="first last simple">
796
- *
797
- * <li>index=2</li>
798
- * </ul>
799
- * </li>
800
- * </ul>
801
- * <p>
802
- * If no option locator prefix is provided, the default behaviour is to match on <strong>label</strong>.
803
- * </p>
804
- *
805
- *
806
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
807
- * @param optionLocator an option locator (a label by default)
808
- */
809
- var element = this.browserbot.findElement(selectLocator);
810
- if (!("options" in element)) {
811
- throw new SeleniumError("Specified element is not a Select (has no options)");
812
- }
813
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
814
- var option = locator.findOption(element);
815
- this.browserbot.selectOption(element, option);
816
- };
817
-
818
-
819
-
820
- Selenium.prototype.doAddSelection = function(locator, optionLocator) {
821
- /**
822
- * Add a selection to the set of selected options in a multi-select element using an option locator.
823
- *
824
- * @see #doSelect for details of option locators
825
- *
826
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
827
- * @param optionLocator an option locator (a label by default)
828
- */
829
- var element = this.browserbot.findElement(locator);
830
- if (!("options" in element)) {
831
- throw new SeleniumError("Specified element is not a Select (has no options)");
832
- }
833
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
834
- var option = locator.findOption(element);
835
- this.browserbot.addSelection(element, option);
836
- };
837
-
838
- Selenium.prototype.doRemoveSelection = function(locator, optionLocator) {
839
- /**
840
- * Remove a selection from the set of selected options in a multi-select element using an option locator.
841
- *
842
- * @see #doSelect for details of option locators
843
- *
844
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
845
- * @param optionLocator an option locator (a label by default)
846
- */
847
-
848
- var element = this.browserbot.findElement(locator);
849
- if (!("options" in element)) {
850
- throw new SeleniumError("Specified element is not a Select (has no options)");
851
- }
852
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
853
- var option = locator.findOption(element);
854
- this.browserbot.removeSelection(element, option);
855
- };
856
-
857
- Selenium.prototype.doRemoveAllSelections = function(locator) {
858
- /**
859
- * Unselects all of the selected options in a multi-select element.
860
- *
861
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
862
- */
863
- var element = this.browserbot.findElement(locator);
864
- if (!("options" in element)) {
865
- throw new SeleniumError("Specified element is not a Select (has no options)");
866
- }
867
- for (var i = 0; i < element.options.length; i++) {
868
- this.browserbot.removeSelection(element, element.options[i]);
869
- }
870
- }
871
-
872
- Selenium.prototype.doSubmit = function(formLocator) {
873
- /**
874
- * Submit the specified form. This is particularly useful for forms without
875
- * submit buttons, e.g. single-input "Search" forms.
876
- *
877
- * @param formLocator an <a href="#locators">element locator</a> for the form you want to submit
878
- */
879
- var form = this.browserbot.findElement(formLocator);
880
- return this.browserbot.submit(form);
881
-
882
- };
883
-
884
- Selenium.prototype.makePageLoadCondition = function(timeout) {
885
- if (timeout == null) {
886
- timeout = this.defaultTimeout;
887
- }
888
- // if the timeout is zero, we won't wait for the page to load before returning
889
- if (timeout == 0) {
890
- return;
891
- }
892
- return Selenium.decorateFunctionWithTimeout(fnBind(this._isNewPageLoaded, this), timeout);
893
- };
894
-
895
- Selenium.prototype.doOpen = function(url) {
896
- /**
897
- * Opens an URL in the test frame. This accepts both relative and absolute
898
- * URLs.
899
- *
900
- * The &quot;open&quot; command waits for the page to load before proceeding,
901
- * ie. the &quot;AndWait&quot; suffix is implicit.
902
- *
903
- * <em>Note</em>: The URL must be on the same domain as the runner HTML
904
- * due to security restrictions in the browser (Same Origin Policy). If you
905
- * need to open an URL on another domain, use the Selenium Server to start a
906
- * new browser session on that domain.
907
- *
908
- * @param url the URL to open; may be relative or absolute
909
- */
910
- this.browserbot.openLocation(url);
911
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
912
- return this.makePageLoadCondition();
913
- } // in PI mode, just return "OK"; the server will waitForLoad
914
- };
915
-
916
- Selenium.prototype.doOpenWindow = function(url, windowID) {
917
- /**
918
- * Opens a popup window (if a window with that ID isn't already open).
919
- * After opening the window, you'll need to select it using the selectWindow
920
- * command.
921
- *
922
- * <p>This command can also be a useful workaround for bug SEL-339. In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example).
923
- * In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using
924
- * an empty (blank) url, like this: openWindow("", "myFunnyWindow").</p>
925
- *
926
- * @param url the URL to open, which can be blank
927
- * @param windowID the JavaScript window ID of the window to select
928
- */
929
- this.browserbot.openWindow(url, windowID);
930
- };
931
-
932
- Selenium.prototype.doSelectWindow = function(windowID) {
933
- /**
934
- * Selects a popup window using a window locator; once a popup window has been selected, all
935
- * commands go to that window. To select the main window again, use null
936
- * as the target.
937
- *
938
- * <p>
939
- *
940
- * Window locators provide different ways of specifying the window object:
941
- * by title, by internal JavaScript "name," or by JavaScript variable.
942
- * </p>
943
- * <ul>
944
- * <li><strong>title</strong>=<em>My Special Window</em>:
945
- * Finds the window using the text that appears in the title bar. Be careful;
946
- * two windows can share the same title. If that happens, this locator will
947
- * just pick one.
948
- * </li>
949
- * <li><strong>name</strong>=<em>myWindow</em>:
950
- * Finds the window using its internal JavaScript "name" property. This is the second
951
- * parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag)
952
- * (which Selenium intercepts).
953
- * </li>
954
- * <li><strong>var</strong>=<em>variableName</em>:
955
- * Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current
956
- * application window, e.g. "window.foo = window.open(url);". In those cases, you can open the window using
957
- * "var=foo".
958
- * </li>
959
- * </ul>
960
- * <p>
961
- * If no window locator prefix is provided, we'll try to guess what you mean like this:</p>
962
- * <p>1.) if windowID is null, (or the string "null") then it is assumed the user is referring to the original window instantiated by the browser).</p>
963
- * <p>2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed
964
- * that this variable contains the return value from a call to the JavaScript window.open() method.</p>
965
- * <p>3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".</p>
966
- * <p>4.) If <em>that</em> fails, we'll try looping over all of the known windows to try to find the appropriate "title".
967
- * Since "title" is not necessarily unique, this may have unexpected behavior.</p>
968
- *
969
- * <p>If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages
970
- * which identify the names of windows created via window.open (and therefore intercepted by Selenium). You will see messages
971
- * like the following for each window as it is opened:</p>
972
- *
973
- * <p><code>debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"</code></p>
974
- *
975
- * <p>In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example).
976
- * (This is bug SEL-339.) In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using
977
- * an empty (blank) url, like this: openWindow("", "myFunnyWindow").</p>
978
- *
979
- * @param windowID the JavaScript window ID of the window to select
980
- */
981
- this.browserbot.selectWindow(windowID);
982
- };
983
-
984
- Selenium.prototype.doSelectFrame = function(locator) {
985
- /**
986
- * Selects a frame within the current window. (You may invoke this command
987
- * multiple times to select nested frames.) To select the parent frame, use
988
- * "relative=parent" as a locator; to select the top frame, use "relative=top".
989
- * You can also select a frame by its 0-based index number; select the first frame with
990
- * "index=0", or the third frame with "index=2".
991
- *
992
- * <p>You may also use a DOM expression to identify the frame you want directly,
993
- * like this: <code>dom=frames["main"].frames["subframe"]</code></p>
994
- *
995
- * @param locator an <a href="#locators">element locator</a> identifying a frame or iframe
996
- */
997
- this.browserbot.selectFrame(locator);
998
- };
999
-
1000
- Selenium.prototype.getWhetherThisFrameMatchFrameExpression = function(currentFrameString, target) {
1001
- /**
1002
- * Determine whether current/locator identify the frame containing this running code.
1003
- *
1004
- * <p>This is useful in proxy injection mode, where this code runs in every
1005
- * browser frame and window, and sometimes the selenium server needs to identify
1006
- * the "current" frame. In this case, when the test calls selectFrame, this
1007
- * routine is called for each frame to figure out which one has been selected.
1008
- * The selected frame will return true, while all others will return false.</p>
1009
- *
1010
- * @param currentFrameString starting frame
1011
- * @param target new frame (which might be relative to the current one)
1012
- * @return boolean true if the new frame is this code's window
1013
- */
1014
- return this.browserbot.doesThisFrameMatchFrameExpression(currentFrameString, target);
1015
- };
1016
-
1017
- Selenium.prototype.getWhetherThisWindowMatchWindowExpression = function(currentWindowString, target) {
1018
- /**
1019
- * Determine whether currentWindowString plus target identify the window containing this running code.
1020
- *
1021
- * <p>This is useful in proxy injection mode, where this code runs in every
1022
- * browser frame and window, and sometimes the selenium server needs to identify
1023
- * the "current" window. In this case, when the test calls selectWindow, this
1024
- * routine is called for each window to figure out which one has been selected.
1025
- * The selected window will return true, while all others will return false.</p>
1026
- *
1027
- * @param currentWindowString starting window
1028
- * @param target new window (which might be relative to the current one, e.g., "_parent")
1029
- * @return boolean true if the new window is this code's window
1030
- */
1031
- if (window.opener!=null && window.opener[target]!=null && window.opener[target]==window) {
1032
- return true;
1033
- }
1034
- return false;
1035
- };
1036
-
1037
- Selenium.prototype.doWaitForPopUp = function(windowID, timeout) {
1038
- /**
1039
- * Waits for a popup window to appear and load up.
1040
- *
1041
- * @param windowID the JavaScript window "name" of the window that will appear (not the text of the title bar)
1042
- * @param timeout a timeout in milliseconds, after which the action will return with an error
1043
- */
1044
- var timeoutTime = getTimeoutTime(timeout);
1045
-
1046
- var popupLoadedPredicate = function () {
1047
- var targetWindow;
1048
- try {
1049
- targetWindow = selenium.browserbot.getWindowByName(windowID, true);
1050
- }
1051
- catch (e) {
1052
- if (new Date().getTime() > timeoutTime) {
1053
- throw e;
1054
- }
1055
- }
1056
-
1057
- if (!targetWindow) return false;
1058
- if (!targetWindow.location) return false;
1059
- if ("about:blank" == targetWindow.location) return false;
1060
- if (browserVersion.isKonqueror) {
1061
- if ("/" == targetWindow.location.href) {
1062
- // apparently Konqueror uses this as the temporary location, instead of about:blank
1063
- return false;
1064
- }
1065
- }
1066
- if (browserVersion.isSafari) {
1067
- if(targetWindow.location.href == selenium.browserbot.buttonWindow.location.href) {
1068
- // Apparently Safari uses this as the temporary location, instead of about:blank
1069
- // what a world!
1070
- LOG.debug("DGF what a world!");
1071
- return false;
1072
- }
1073
- }
1074
- if (!targetWindow.document) return false;
1075
- if (!selenium.browserbot.getCurrentWindow().document.readyState) {
1076
- // This is Firefox, with no readyState extension
1077
- return true;
1078
- }
1079
- if ('complete' != targetWindow.document.readyState) return false;
1080
- return true;
1081
- };
1082
-
1083
- return Selenium.decorateFunctionWithTimeout(popupLoadedPredicate, timeout);
1084
- }
1085
-
1086
- Selenium.prototype.doWaitForPopUp.dontCheckAlertsAndConfirms = true;
1087
-
1088
- Selenium.prototype.doChooseCancelOnNextConfirmation = function() {
1089
- /**
1090
- * <p>
1091
- * By default, Selenium's overridden window.confirm() function will
1092
- * return true, as if the user had manually clicked OK; after running
1093
- * this command, the next call to confirm() will return false, as if
1094
- * the user had clicked Cancel. Selenium will then resume using the
1095
- * default behavior for future confirmations, automatically returning
1096
- * true (OK) unless/until you explicitly call this command for each
1097
- * confirmation.
1098
- * </p>
1099
- * <p>
1100
- * Take note - every time a confirmation comes up, you must
1101
- * consume it with a corresponding getConfirmation, or else
1102
- * the next selenium operation will fail.
1103
- * </p>
1104
- */
1105
- this.browserbot.cancelNextConfirmation(false);
1106
- };
1107
-
1108
- Selenium.prototype.doChooseOkOnNextConfirmation = function() {
1109
- /**
1110
- * <p>
1111
- * Undo the effect of calling chooseCancelOnNextConfirmation. Note
1112
- * that Selenium's overridden window.confirm() function will normally automatically
1113
- * return true, as if the user had manually clicked OK, so you shouldn't
1114
- * need to use this command unless for some reason you need to change
1115
- * your mind prior to the next confirmation. After any confirmation, Selenium will resume using the
1116
- * default behavior for future confirmations, automatically returning
1117
- * true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each
1118
- * confirmation.
1119
- * </p>
1120
- * <p>
1121
- * Take note - every time a confirmation comes up, you must
1122
- * consume it with a corresponding getConfirmation, or else
1123
- * the next selenium operation will fail.
1124
- * </p>
1125
- *
1126
- */
1127
- this.browserbot.cancelNextConfirmation(true);
1128
- };
1129
-
1130
- Selenium.prototype.doAnswerOnNextPrompt = function(answer) {
1131
- /**
1132
- * Instructs Selenium to return the specified answer string in response to
1133
- * the next JavaScript prompt [window.prompt()].
1134
- *
1135
- *
1136
- * @param answer the answer to give in response to the prompt pop-up
1137
- */
1138
- this.browserbot.setNextPromptResult(answer);
1139
- };
1140
-
1141
- Selenium.prototype.doGoBack = function() {
1142
- /**
1143
- * Simulates the user clicking the "back" button on their browser.
1144
- *
1145
- */
1146
- this.browserbot.goBack();
1147
- };
1148
-
1149
- Selenium.prototype.doRefresh = function() {
1150
- /**
1151
- * Simulates the user clicking the "Refresh" button on their browser.
1152
- *
1153
- */
1154
- this.browserbot.refresh();
1155
- };
1156
-
1157
- Selenium.prototype.doClose = function() {
1158
- /**
1159
- * Simulates the user clicking the "close" button in the titlebar of a popup
1160
- * window or tab.
1161
- */
1162
- this.browserbot.close();
1163
- };
1164
-
1165
- Selenium.prototype.ensureNoUnhandledPopups = function() {
1166
- if (this.browserbot.hasAlerts()) {
1167
- throw new SeleniumError("There was an unexpected Alert! [" + this.browserbot.getNextAlert() + "]");
1168
- }
1169
- if ( this.browserbot.hasConfirmations() ) {
1170
- throw new SeleniumError("There was an unexpected Confirmation! [" + this.browserbot.getNextConfirmation() + "]");
1171
- }
1172
- };
1173
-
1174
- Selenium.prototype.isAlertPresent = function() {
1175
- /**
1176
- * Has an alert occurred?
1177
- *
1178
- * <p>
1179
- * This function never throws an exception
1180
- * </p>
1181
- * @return boolean true if there is an alert
1182
- */
1183
- return this.browserbot.hasAlerts();
1184
- };
1185
-
1186
- Selenium.prototype.isPromptPresent = function() {
1187
- /**
1188
- * Has a prompt occurred?
1189
- *
1190
- * <p>
1191
- * This function never throws an exception
1192
- * </p>
1193
- * @return boolean true if there is a pending prompt
1194
- */
1195
- return this.browserbot.hasPrompts();
1196
- };
1197
-
1198
- Selenium.prototype.isConfirmationPresent = function() {
1199
- /**
1200
- * Has confirm() been called?
1201
- *
1202
- * <p>
1203
- * This function never throws an exception
1204
- * </p>
1205
- * @return boolean true if there is a pending confirmation
1206
- */
1207
- return this.browserbot.hasConfirmations();
1208
- };
1209
- Selenium.prototype.getAlert = function() {
1210
- /**
1211
- * Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts.
1212
- *
1213
- * <p>Getting an alert has the same effect as manually clicking OK. If an
1214
- * alert is generated but you do not consume it with getAlert, the next Selenium action
1215
- * will fail.</p>
1216
- *
1217
- * <p>Under Selenium, JavaScript alerts will NOT pop up a visible alert
1218
- * dialog.</p>
1219
- *
1220
- * <p>Selenium does NOT support JavaScript alerts that are generated in a
1221
- * page's onload() event handler. In this case a visible dialog WILL be
1222
- * generated and Selenium will hang until someone manually clicks OK.</p>
1223
- * @return string The message of the most recent JavaScript alert
1224
-
1225
- */
1226
- if (!this.browserbot.hasAlerts()) {
1227
- Assert.fail("There were no alerts");
1228
- }
1229
- return this.browserbot.getNextAlert();
1230
- };
1231
- Selenium.prototype.getAlert.dontCheckAlertsAndConfirms = true;
1232
-
1233
- Selenium.prototype.getConfirmation = function() {
1234
- /**
1235
- * Retrieves the message of a JavaScript confirmation dialog generated during
1236
- * the previous action.
1237
- *
1238
- * <p>
1239
- * By default, the confirm function will return true, having the same effect
1240
- * as manually clicking OK. This can be changed by prior execution of the
1241
- * chooseCancelOnNextConfirmation command.
1242
- * </p>
1243
- * <p>
1244
- * If an confirmation is generated but you do not consume it with getConfirmation,
1245
- * the next Selenium action will fail.
1246
- * </p>
1247
- *
1248
- * <p>
1249
- * NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible
1250
- * dialog.
1251
- * </p>
1252
- *
1253
- * <p>
1254
- * NOTE: Selenium does NOT support JavaScript confirmations that are
1255
- * generated in a page's onload() event handler. In this case a visible
1256
- * dialog WILL be generated and Selenium will hang until you manually click
1257
- * OK.
1258
- * </p>
1259
- *
1260
- * @return string the message of the most recent JavaScript confirmation dialog
1261
- */
1262
- if (!this.browserbot.hasConfirmations()) {
1263
- Assert.fail("There were no confirmations");
1264
- }
1265
- return this.browserbot.getNextConfirmation();
1266
- };
1267
- Selenium.prototype.getConfirmation.dontCheckAlertsAndConfirms = true;
1268
-
1269
- Selenium.prototype.getPrompt = function() {
1270
- /**
1271
- * Retrieves the message of a JavaScript question prompt dialog generated during
1272
- * the previous action.
1273
- *
1274
- * <p>Successful handling of the prompt requires prior execution of the
1275
- * answerOnNextPrompt command. If a prompt is generated but you
1276
- * do not get/verify it, the next Selenium action will fail.</p>
1277
- *
1278
- * <p>NOTE: under Selenium, JavaScript prompts will NOT pop up a visible
1279
- * dialog.</p>
1280
- *
1281
- * <p>NOTE: Selenium does NOT support JavaScript prompts that are generated in a
1282
- * page's onload() event handler. In this case a visible dialog WILL be
1283
- * generated and Selenium will hang until someone manually clicks OK.</p>
1284
- * @return string the message of the most recent JavaScript question prompt
1285
- */
1286
- if (! this.browserbot.hasPrompts()) {
1287
- Assert.fail("There were no prompts");
1288
- }
1289
- return this.browserbot.getNextPrompt();
1290
- };
1291
-
1292
- Selenium.prototype.getLocation = function() {
1293
- /** Gets the absolute URL of the current page.
1294
- *
1295
- * @return string the absolute URL of the current page
1296
- */
1297
- return this.browserbot.getCurrentWindow().location.href;
1298
- };
1299
-
1300
- Selenium.prototype.getTitle = function() {
1301
- /** Gets the title of the current page.
1302
- *
1303
- * @return string the title of the current page
1304
- */
1305
- return this.browserbot.getTitle();
1306
- };
1307
-
1308
-
1309
- Selenium.prototype.getBodyText = function() {
1310
- /**
1311
- * Gets the entire text of the page.
1312
- * @return string the entire text of the page
1313
- */
1314
- return this.browserbot.bodyText();
1315
- };
1316
-
1317
-
1318
- Selenium.prototype.getValue = function(locator) {
1319
- /**
1320
- * Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter).
1321
- * For checkbox/radio elements, the value will be "on" or "off" depending on
1322
- * whether the element is checked or not.
1323
- *
1324
- * @param locator an <a href="#locators">element locator</a>
1325
- * @return string the element value, or "on/off" for checkbox/radio elements
1326
- */
1327
- var element = this.browserbot.findElement(locator)
1328
- return getInputValue(element).trim();
1329
- }
1330
-
1331
- Selenium.prototype.getText = function(locator) {
1332
- /**
1333
- * Gets the text of an element. This works for any element that contains
1334
- * text. This command uses either the textContent (Mozilla-like browsers) or
1335
- * the innerText (IE-like browsers) of the element, which is the rendered
1336
- * text shown to the user.
1337
- *
1338
- * @param locator an <a href="#locators">element locator</a>
1339
- * @return string the text of the element
1340
- */
1341
- var element = this.browserbot.findElement(locator);
1342
- return getText(element).trim();
1343
- };
1344
-
1345
- Selenium.prototype.doHighlight = function(locator) {
1346
- /**
1347
- * Briefly changes the backgroundColor of the specified element yellow. Useful for debugging.
1348
- *
1349
- * @param locator an <a href="#locators">element locator</a>
1350
- */
1351
- var element = this.browserbot.findElement(locator);
1352
- this.browserbot.highlight(element, true);
1353
- };
1354
-
1355
- Selenium.prototype.getEval = function(script) {
1356
- /** Gets the result of evaluating the specified JavaScript snippet. The snippet may
1357
- * have multiple lines, but only the result of the last line will be returned.
1358
- *
1359
- * <p>Note that, by default, the snippet will run in the context of the "selenium"
1360
- * object itself, so <code>this</code> will refer to the Selenium object. Use <code>window</code> to
1361
- * refer to the window of your application, e.g. <code>window.document.getElementById('foo')</code></p>
1362
- *
1363
- * <p>If you need to use
1364
- * a locator to refer to a single element in your application page, you can
1365
- * use <code>this.browserbot.findElement("id=foo")</code> where "id=foo" is your locator.</p>
1366
- *
1367
- * @param script the JavaScript snippet to run
1368
- * @return string the results of evaluating the snippet
1369
- */
1370
- try {
1371
- var window = this.browserbot.getCurrentWindow();
1372
- var result = eval(script);
1373
- // Selenium RC doesn't allow returning null
1374
- if (null == result) return "null";
1375
- return result;
1376
- } catch (e) {
1377
- throw new SeleniumError("Threw an exception: " + extractExceptionMessage(e));
1378
- }
1379
- };
1380
-
1381
- Selenium.prototype.isChecked = function(locator) {
1382
- /**
1383
- * Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button.
1384
- * @param locator an <a href="#locators">element locator</a> pointing to a checkbox or radio button
1385
- * @return boolean true if the checkbox is checked, false otherwise
1386
- */
1387
- var element = this.browserbot.findElement(locator);
1388
- if (element.checked == null) {
1389
- throw new SeleniumError("Element " + locator + " is not a toggle-button.");
1390
- }
1391
- return element.checked;
1392
- };
1393
-
1394
- Selenium.prototype.getTable = function(tableCellAddress) {
1395
- /**
1396
- * Gets the text from a cell of a table. The cellAddress syntax
1397
- * tableLocator.row.column, where row and column start at 0.
1398
- *
1399
- * @param tableCellAddress a cell address, e.g. "foo.1.4"
1400
- * @return string the text from the specified cell
1401
- */
1402
- // This regular expression matches "tableName.row.column"
1403
- // For example, "mytable.3.4"
1404
- pattern = /(.*)\.(\d+)\.(\d+)/;
1405
-
1406
- if(!pattern.test(tableCellAddress)) {
1407
- throw new SeleniumError("Invalid target format. Correct format is tableName.rowNum.columnNum");
1408
- }
1409
-
1410
- pieces = tableCellAddress.match(pattern);
1411
-
1412
- tableName = pieces[1];
1413
- row = pieces[2];
1414
- col = pieces[3];
1415
-
1416
- var table = this.browserbot.findElement(tableName);
1417
- if (row > table.rows.length) {
1418
- Assert.fail("Cannot access row " + row + " - table has " + table.rows.length + " rows");
1419
- }
1420
- else if (col > table.rows[row].cells.length) {
1421
- Assert.fail("Cannot access column " + col + " - table row has " + table.rows[row].cells.length + " columns");
1422
- }
1423
- else {
1424
- actualContent = getText(table.rows[row].cells[col]);
1425
- return actualContent.trim();
1426
- }
1427
- return null;
1428
- };
1429
-
1430
- Selenium.prototype.getSelectedLabels = function(selectLocator) {
1431
- /** Gets all option labels (visible text) for selected options in the specified select or multi-select element.
1432
- *
1433
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1434
- * @return string[] an array of all selected option labels in the specified select drop-down
1435
- */
1436
- return this.findSelectedOptionProperties(selectLocator, "text");
1437
- }
1438
-
1439
- Selenium.prototype.getSelectedLabel = function(selectLocator) {
1440
- /** Gets option label (visible text) for selected option in the specified select element.
1441
- *
1442
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1443
- * @return string the selected option label in the specified select drop-down
1444
- */
1445
- return this.findSelectedOptionProperty(selectLocator, "text");
1446
- }
1447
-
1448
- Selenium.prototype.getSelectedValues = function(selectLocator) {
1449
- /** Gets all option values (value attributes) for selected options in the specified select or multi-select element.
1450
- *
1451
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1452
- * @return string[] an array of all selected option values in the specified select drop-down
1453
- */
1454
- return this.findSelectedOptionProperties(selectLocator, "value");
1455
- }
1456
-
1457
- Selenium.prototype.getSelectedValue = function(selectLocator) {
1458
- /** Gets option value (value attribute) for selected option in the specified select element.
1459
- *
1460
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1461
- * @return string the selected option value in the specified select drop-down
1462
- */
1463
- return this.findSelectedOptionProperty(selectLocator, "value");
1464
- }
1465
-
1466
- Selenium.prototype.getSelectedIndexes = function(selectLocator) {
1467
- /** Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.
1468
- *
1469
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1470
- * @return string[] an array of all selected option indexes in the specified select drop-down
1471
- */
1472
- return this.findSelectedOptionProperties(selectLocator, "index");
1473
- }
1474
-
1475
- Selenium.prototype.getSelectedIndex = function(selectLocator) {
1476
- /** Gets option index (option number, starting at 0) for selected option in the specified select element.
1477
- *
1478
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1479
- * @return string the selected option index in the specified select drop-down
1480
- */
1481
- return this.findSelectedOptionProperty(selectLocator, "index");
1482
- }
1483
-
1484
- Selenium.prototype.getSelectedIds = function(selectLocator) {
1485
- /** Gets all option element IDs for selected options in the specified select or multi-select element.
1486
- *
1487
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1488
- * @return string[] an array of all selected option IDs in the specified select drop-down
1489
- */
1490
- return this.findSelectedOptionProperties(selectLocator, "id");
1491
- }
1492
-
1493
- Selenium.prototype.getSelectedId = function(selectLocator) {
1494
- /** Gets option element ID for selected option in the specified select element.
1495
- *
1496
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1497
- * @return string the selected option ID in the specified select drop-down
1498
- */
1499
- return this.findSelectedOptionProperty(selectLocator, "id");
1500
- }
1501
-
1502
- Selenium.prototype.isSomethingSelected = function(selectLocator) {
1503
- /** Determines whether some option in a drop-down menu is selected.
1504
- *
1505
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1506
- * @return boolean true if some option has been selected, false otherwise
1507
- */
1508
- var element = this.browserbot.findElement(selectLocator);
1509
- if (!("options" in element)) {
1510
- throw new SeleniumError("Specified element is not a Select (has no options)");
1511
- }
1512
-
1513
- var selectedOptions = [];
1514
-
1515
- for (var i = 0; i < element.options.length; i++) {
1516
- if (element.options[i].selected)
1517
- {
1518
- return true;
1519
- }
1520
- }
1521
- return false;
1522
- }
1523
-
1524
- Selenium.prototype.findSelectedOptionProperties = function(locator, property) {
1525
- var element = this.browserbot.findElement(locator);
1526
- if (!("options" in element)) {
1527
- throw new SeleniumError("Specified element is not a Select (has no options)");
1528
- }
1529
-
1530
- var selectedOptions = [];
1531
-
1532
- for (var i = 0; i < element.options.length; i++) {
1533
- if (element.options[i].selected)
1534
- {
1535
- var propVal = element.options[i][property];
1536
- selectedOptions.push(propVal);
1537
- }
1538
- }
1539
- if (selectedOptions.length == 0) Assert.fail("No option selected");
1540
- return selectedOptions;
1541
- }
1542
-
1543
- Selenium.prototype.findSelectedOptionProperty = function(locator, property) {
1544
- var selectedOptions = this.findSelectedOptionProperties(locator, property);
1545
- if (selectedOptions.length > 1) {
1546
- Assert.fail("More than one selected option!");
1547
- }
1548
- return selectedOptions[0];
1549
- }
1550
-
1551
- Selenium.prototype.getSelectOptions = function(selectLocator) {
1552
- /** Gets all option labels in the specified select drop-down.
1553
- *
1554
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1555
- * @return string[] an array of all option labels in the specified select drop-down
1556
- */
1557
- var element = this.browserbot.findElement(selectLocator);
1558
-
1559
- var selectOptions = [];
1560
-
1561
- for (var i = 0; i < element.options.length; i++) {
1562
- var option = element.options[i].text;
1563
- selectOptions.push(option);
1564
- }
1565
-
1566
- return selectOptions;
1567
- };
1568
-
1569
-
1570
- Selenium.prototype.getAttribute = function(attributeLocator) {
1571
- /**
1572
- * Gets the value of an element attribute. The value of the attribute may
1573
- * differ across browsers (this is the case for the "style" attribute, for
1574
- * example).
1575
- *
1576
- * @param attributeLocator an element locator followed by an &#064; sign and then the name of the attribute, e.g. "foo&#064;bar"
1577
- * @return string the value of the specified attribute
1578
- */
1579
- var result = this.browserbot.findAttribute(attributeLocator);
1580
- if (result == null) {
1581
- throw new SeleniumError("Could not find element attribute: " + attributeLocator);
1582
- }
1583
- return result;
1584
- };
1585
-
1586
- Selenium.prototype.isTextPresent = function(pattern) {
1587
- /**
1588
- * Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.
1589
- * @param pattern a <a href="#patterns">pattern</a> to match with the text of the page
1590
- * @return boolean true if the pattern matches the text, false otherwise
1591
- */
1592
- var allText = this.browserbot.bodyText();
1593
-
1594
- var patternMatcher = new PatternMatcher(pattern);
1595
- if (patternMatcher.strategy == PatternMatcher.strategies.glob) {
1596
- if (pattern.indexOf("glob:")==0) {
1597
- pattern = pattern.substring("glob:".length); // strip off "glob:"
1598
- }
1599
- patternMatcher.matcher = new PatternMatcher.strategies.globContains(pattern);
1600
- }
1601
- else if (patternMatcher.strategy == PatternMatcher.strategies.exact) {
1602
- pattern = pattern.substring("exact:".length); // strip off "exact:"
1603
- return allText.indexOf(pattern) != -1;
1604
- }
1605
- return patternMatcher.matches(allText);
1606
- };
1607
-
1608
- Selenium.prototype.isElementPresent = function(locator) {
1609
- /**
1610
- * Verifies that the specified element is somewhere on the page.
1611
- * @param locator an <a href="#locators">element locator</a>
1612
- * @return boolean true if the element is present, false otherwise
1613
- */
1614
- var element = this.browserbot.findElementOrNull(locator);
1615
- if (element == null) {
1616
- return false;
1617
- }
1618
- return true;
1619
- };
1620
-
1621
- Selenium.prototype.isVisible = function(locator) {
1622
- /**
1623
- * Determines if the specified element is visible. An
1624
- * element can be rendered invisible by setting the CSS "visibility"
1625
- * property to "hidden", or the "display" property to "none", either for the
1626
- * element itself or one if its ancestors. This method will fail if
1627
- * the element is not present.
1628
- *
1629
- * @param locator an <a href="#locators">element locator</a>
1630
- * @return boolean true if the specified element is visible, false otherwise
1631
- */
1632
- var element;
1633
- element = this.browserbot.findElement(locator);
1634
- // DGF if it's an input tag of type "hidden" then it's not visible
1635
- if (element.tagName) {
1636
- var tagName = new String(element.tagName).toLowerCase();
1637
- if (tagName == "input") {
1638
- if (element.type) {
1639
- var elementType = new String(element.type).toLowerCase();
1640
- if (elementType == "hidden") {
1641
- return false;
1642
- }
1643
- }
1644
- }
1645
- }
1646
- var visibility = this.findEffectiveStyleProperty(element, "visibility");
1647
- var _isDisplayed = this._isDisplayed(element);
1648
- return (visibility != "hidden" && _isDisplayed);
1649
- };
1650
-
1651
- Selenium.prototype.findEffectiveStyleProperty = function(element, property) {
1652
- var effectiveStyle = this.findEffectiveStyle(element);
1653
- var propertyValue = effectiveStyle[property];
1654
- if (propertyValue == 'inherit' && element.parentNode.style) {
1655
- return this.findEffectiveStyleProperty(element.parentNode, property);
1656
- }
1657
- return propertyValue;
1658
- };
1659
-
1660
- Selenium.prototype._isDisplayed = function(element) {
1661
- var display = this.findEffectiveStyleProperty(element, "display");
1662
- if (display == "none") return false;
1663
- if (element.parentNode.style) {
1664
- return this._isDisplayed(element.parentNode);
1665
- }
1666
- return true;
1667
- };
1668
-
1669
- Selenium.prototype.findEffectiveStyle = function(element) {
1670
- if (element.style == undefined) {
1671
- return undefined; // not a styled element
1672
- }
1673
- var window = this.browserbot.getCurrentWindow();
1674
- if (window.getComputedStyle) {
1675
- // DOM-Level-2-CSS
1676
- return window.getComputedStyle(element, null);
1677
- }
1678
- if (element.currentStyle) {
1679
- // non-standard IE alternative
1680
- return element.currentStyle;
1681
- // TODO: this won't really work in a general sense, as
1682
- // currentStyle is not identical to getComputedStyle()
1683
- // ... but it's good enough for "visibility"
1684
- }
1685
-
1686
- if (window.document.defaultView && window.document.defaultView.getComputedStyle) {
1687
- return window.document.defaultView.getComputedStyle(element, null);
1688
- }
1689
-
1690
-
1691
- throw new SeleniumError("cannot determine effective stylesheet in this browser");
1692
- };
1693
-
1694
- Selenium.prototype.isEditable = function(locator) {
1695
- /**
1696
- * Determines whether the specified input element is editable, ie hasn't been disabled.
1697
- * This method will fail if the specified element isn't an input element.
1698
- *
1699
- * @param locator an <a href="#locators">element locator</a>
1700
- * @return boolean true if the input element is editable, false otherwise
1701
- */
1702
- var element = this.browserbot.findElement(locator);
1703
- if (element.value == undefined) {
1704
- Assert.fail("Element " + locator + " is not an input.");
1705
- }
1706
- if (element.disabled) {
1707
- return false;
1708
- }
1709
- // DGF "readonly" is a bit goofy... it doesn't necessarily have a value
1710
- // You can write <input readonly value="black">
1711
- var readOnlyNode = element.getAttributeNode('readonly');
1712
- if (readOnlyNode) {
1713
- // DGF on IE, every input element has a readOnly node, but it may be false
1714
- if (typeof(readOnlyNode.nodeValue) == "boolean") {
1715
- var readOnly = readOnlyNode.nodeValue;
1716
- if (readOnly) {
1717
- return false;
1718
- }
1719
- } else {
1720
- return false;
1721
- }
1722
- }
1723
- return true;
1724
- };
1725
-
1726
- Selenium.prototype.getAllButtons = function() {
1727
- /** Returns the IDs of all buttons on the page.
1728
- *
1729
- * <p>If a given button has no ID, it will appear as "" in this array.</p>
1730
- *
1731
- * @return string[] the IDs of all buttons on the page
1732
- */
1733
- return this.browserbot.getAllButtons();
1734
- };
1735
-
1736
- Selenium.prototype.getAllLinks = function() {
1737
- /** Returns the IDs of all links on the page.
1738
- *
1739
- * <p>If a given link has no ID, it will appear as "" in this array.</p>
1740
- *
1741
- * @return string[] the IDs of all links on the page
1742
- */
1743
- return this.browserbot.getAllLinks();
1744
- };
1745
-
1746
- Selenium.prototype.getAllFields = function() {
1747
- /** Returns the IDs of all input fields on the page.
1748
- *
1749
- * <p>If a given field has no ID, it will appear as "" in this array.</p>
1750
- *
1751
- * @return string[] the IDs of all field on the page
1752
- */
1753
- return this.browserbot.getAllFields();
1754
- };
1755
-
1756
- Selenium.prototype.getAttributeFromAllWindows = function(attributeName) {
1757
- /** Returns every instance of some attribute from all known windows.
1758
- *
1759
- * @param attributeName name of an attribute on the windows
1760
- * @return string[] the set of values of this attribute from all known windows.
1761
- */
1762
- var attributes = new Array();
1763
-
1764
- var win = selenium.browserbot.topWindow;
1765
-
1766
- // DGF normally you should use []s instead of eval "win."+attributeName
1767
- // but in this case, attributeName may contain dots (e.g. document.title)
1768
- // in that case, we have no choice but to use eval...
1769
- attributes.push(eval("win."+attributeName));
1770
- for (var windowName in this.browserbot.openedWindows)
1771
- {
1772
- try {
1773
- win = selenium.browserbot.openedWindows[windowName];
1774
- attributes.push(eval("win."+attributeName));
1775
- } catch (e) {} // DGF If we miss one... meh. It's probably closed or inaccessible anyway.
1776
- }
1777
- return attributes;
1778
- };
1779
-
1780
- Selenium.prototype.findWindow = function(soughtAfterWindowPropertyValue) {
1781
- var targetPropertyName = "name";
1782
- if (soughtAfterWindowPropertyValue.match("^title=")) {
1783
- targetPropertyName = "document.title";
1784
- soughtAfterWindowPropertyValue = soughtAfterWindowPropertyValue.replace(/^title=/, "");
1785
- }
1786
- else {
1787
- // matching "name":
1788
- // If we are not in proxy injection mode, then the top-level test window will be named selenium_myiframe.
1789
- // But as far as the interface goes, we are expected to match a blank string to this window, if
1790
- // we are searching with respect to the widow name.
1791
- // So make a special case so that this logic will work:
1792
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, "")) {
1793
- return this.browserbot.getCurrentWindow();
1794
- }
1795
- }
1796
-
1797
- // DGF normally you should use []s instead of eval "win."+attributeName
1798
- // but in this case, attributeName may contain dots (e.g. document.title)
1799
- // in that case, we have no choice but to use eval...
1800
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("this.browserbot.topWindow." + targetPropertyName))) {
1801
- return this.browserbot.topWindow;
1802
- }
1803
- for (windowName in selenium.browserbot.openedWindows) {
1804
- var openedWindow = selenium.browserbot.openedWindows[windowName];
1805
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("openedWindow." + targetPropertyName))) {
1806
- return openedWindow;
1807
- }
1808
- }
1809
- throw new SeleniumError("could not find window with property " + targetPropertyName + " matching " + soughtAfterWindowPropertyValue);
1810
- };
1811
-
1812
- Selenium.prototype.doDragdrop = function(locator, movementsString) {
1813
- /** deprecated - use dragAndDrop instead
1814
- *
1815
- * @param locator an element locator
1816
- * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
1817
- */
1818
- this.doDragAndDrop(locator, movementsString);
1819
- };
1820
-
1821
- Selenium.prototype.doSetMouseSpeed = function(pixels) {
1822
- /** Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
1823
- * <p>Setting this value to 0 means that we'll send a "mousemove" event to every single pixel
1824
- * in between the start location and the end location; that can be very slow, and may
1825
- * cause some browsers to force the JavaScript to timeout.</p>
1826
- *
1827
- * <p>If the mouse speed is greater than the distance between the two dragged objects, we'll
1828
- * just send one "mousemove" at the start location and then one final one at the end location.</p>
1829
- * @param pixels the number of pixels between "mousemove" events
1830
- */
1831
- this.mouseSpeed = pixels;
1832
- }
1833
-
1834
- Selenium.prototype.getMouseSpeed = function() {
1835
- /** Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
1836
- *
1837
- * @return number the number of pixels between "mousemove" events during dragAndDrop commands (default=10)
1838
- */
1839
- this.mouseSpeed = pixels;
1840
- }
1841
-
1842
-
1843
- Selenium.prototype.doDragAndDrop = function(locator, movementsString) {
1844
- /** Drags an element a certain distance and then drops it
1845
- * @param locator an element locator
1846
- * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
1847
- */
1848
- var element = this.browserbot.findElement(locator);
1849
- var clientStartXY = getClientXY(element)
1850
- var clientStartX = clientStartXY[0];
1851
- var clientStartY = clientStartXY[1];
1852
-
1853
- var movements = movementsString.split(/,/);
1854
- var movementX = Number(movements[0]);
1855
- var movementY = Number(movements[1]);
1856
-
1857
- var clientFinishX = ((clientStartX + movementX) < 0) ? 0 : (clientStartX + movementX);
1858
- var clientFinishY = ((clientStartY + movementY) < 0) ? 0 : (clientStartY + movementY);
1859
-
1860
- var mouseSpeed = this.mouseSpeed;
1861
- var move = function(current, dest) {
1862
- if (current == dest) return current;
1863
- if (Math.abs(current - dest) < mouseSpeed) return dest;
1864
- return (current < dest) ? current + mouseSpeed : current - mouseSpeed;
1865
- }
1866
-
1867
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientStartX, clientStartY);
1868
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientStartX, clientStartY);
1869
- var clientX = clientStartX;
1870
- var clientY = clientStartY;
1871
-
1872
- while ((clientX != clientFinishX) || (clientY != clientFinishY)) {
1873
- clientX = move(clientX, clientFinishX);
1874
- clientY = move(clientY, clientFinishY);
1875
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientX, clientY);
1876
- }
1877
-
1878
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientFinishX, clientFinishY);
1879
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientFinishX, clientFinishY);
1880
- };
1881
-
1882
- Selenium.prototype.doDragAndDropToObject = function(locatorOfObjectToBeDragged, locatorOfDragDestinationObject) {
1883
- /** Drags an element and drops it on another element
1884
- *
1885
- * @param locatorOfObjectToBeDragged an element to be dragged
1886
- * @param locatorOfDragDestinationObject an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged is dropped
1887
- */
1888
- var startX = this.getElementPositionLeft(locatorOfObjectToBeDragged);
1889
- var startY = this.getElementPositionTop(locatorOfObjectToBeDragged);
1890
-
1891
- var destinationLeftX = this.getElementPositionLeft(locatorOfDragDestinationObject);
1892
- var destinationTopY = this.getElementPositionTop(locatorOfDragDestinationObject);
1893
- var destinationWidth = this.getElementWidth(locatorOfDragDestinationObject);
1894
- var destinationHeight = this.getElementHeight(locatorOfDragDestinationObject);
1895
-
1896
- var endX = Math.round(destinationLeftX + (destinationWidth / 2));
1897
- var endY = Math.round(destinationTopY + (destinationHeight / 2));
1898
-
1899
- var deltaX = endX - startX;
1900
- var deltaY = endY - startY;
1901
-
1902
- var movementsString = "" + deltaX + "," + deltaY;
1903
-
1904
- this.doDragAndDrop(locatorOfObjectToBeDragged, movementsString);
1905
- };
1906
-
1907
- Selenium.prototype.doWindowFocus = function() {
1908
- /** Gives focus to the currently selected window
1909
- *
1910
- */
1911
- this.browserbot.getCurrentWindow().focus();
1912
- };
1913
-
1914
-
1915
- Selenium.prototype.doWindowMaximize = function() {
1916
- /** Resize currently selected window to take up the entire screen
1917
- *
1918
- */
1919
- var window = this.browserbot.getCurrentWindow();
1920
- if (window!=null && window.screen) {
1921
- window.moveTo(0,0);
1922
- window.resizeTo(screen.availWidth, screen.availHeight);
1923
- }
1924
- };
1925
-
1926
- Selenium.prototype.getAllWindowIds = function() {
1927
- /** Returns the IDs of all windows that the browser knows about.
1928
- *
1929
- * @return string[] the IDs of all windows that the browser knows about.
1930
- */
1931
- return this.getAttributeFromAllWindows("id");
1932
- };
1933
-
1934
- Selenium.prototype.getAllWindowNames = function() {
1935
- /** Returns the names of all windows that the browser knows about.
1936
- *
1937
- * @return string[] the names of all windows that the browser knows about.
1938
- */
1939
- return this.getAttributeFromAllWindows("name");
1940
- };
1941
-
1942
- Selenium.prototype.getAllWindowTitles = function() {
1943
- /** Returns the titles of all windows that the browser knows about.
1944
- *
1945
- * @return string[] the titles of all windows that the browser knows about.
1946
- */
1947
- return this.getAttributeFromAllWindows("document.title");
1948
- };
1949
-
1950
- Selenium.prototype.getHtmlSource = function() {
1951
- /** Returns the entire HTML source between the opening and
1952
- * closing "html" tags.
1953
- *
1954
- * @return string the entire HTML source
1955
- */
1956
- return this.browserbot.getDocument().getElementsByTagName("html")[0].innerHTML;
1957
- };
1958
-
1959
- Selenium.prototype.doSetCursorPosition = function(locator, position) {
1960
- /**
1961
- * Moves the text cursor to the specified position in the given input element or textarea.
1962
- * This method will fail if the specified element isn't an input element or textarea.
1963
- *
1964
- * @param locator an <a href="#locators">element locator</a> pointing to an input element or textarea
1965
- * @param position the numerical position of the cursor in the field; position should be 0 to move the position to the beginning of the field. You can also set the cursor to -1 to move it to the end of the field.
1966
- */
1967
- var element = this.browserbot.findElement(locator);
1968
- if (element.value == undefined) {
1969
- Assert.fail("Element " + locator + " is not an input.");
1970
- }
1971
- if (position == -1) {
1972
- position = element.value.length;
1973
- }
1974
-
1975
- if( element.setSelectionRange && !browserVersion.isOpera) {
1976
- element.focus();
1977
- element.setSelectionRange(/*start*/position,/*end*/position);
1978
- }
1979
- else if( element.createTextRange ) {
1980
- triggerEvent(element, 'focus', false);
1981
- var range = element.createTextRange();
1982
- range.collapse(true);
1983
- range.moveEnd('character',position);
1984
- range.moveStart('character',position);
1985
- range.select();
1986
- }
1987
- }
1988
-
1989
- Selenium.prototype.getElementIndex = function(locator) {
1990
- /**
1991
- * Get the relative index of an element to its parent (starting from 0). The comment node and empty text node
1992
- * will be ignored.
1993
- *
1994
- * @param locator an <a href="#locators">element locator</a> pointing to an element
1995
- * @return number of relative index of the element to its parent (starting from 0)
1996
- */
1997
- var element = this.browserbot.findElement(locator);
1998
- var previousSibling;
1999
- var index = 0;
2000
- while ((previousSibling = element.previousSibling) != null) {
2001
- if (!this._isCommentOrEmptyTextNode(previousSibling)) {
2002
- index++;
2003
- }
2004
- element = previousSibling;
2005
- }
2006
- return index;
2007
- }
2008
-
2009
- Selenium.prototype.isOrdered = function(locator1, locator2) {
2010
- /**
2011
- * Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will
2012
- * not be considered ordered.
2013
- *
2014
- * @param locator1 an <a href="#locators">element locator</a> pointing to the first element
2015
- * @param locator2 an <a href="#locators">element locator</a> pointing to the second element
2016
- * @return boolean true if element1 is the previous sibling of element2, false otherwise
2017
- */
2018
- var element1 = this.browserbot.findElement(locator1);
2019
- var element2 = this.browserbot.findElement(locator2);
2020
- if (element1 === element2) return false;
2021
-
2022
- var previousSibling;
2023
- while ((previousSibling = element2.previousSibling) != null) {
2024
- if (previousSibling === element1) {
2025
- return true;
2026
- }
2027
- element2 = previousSibling;
2028
- }
2029
- return false;
2030
- }
2031
-
2032
- Selenium.prototype._isCommentOrEmptyTextNode = function(node) {
2033
- return node.nodeType == 8 || ((node.nodeType == 3) && !(/[^\t\n\r ]/.test(node.data)));
2034
- }
2035
-
2036
- Selenium.prototype.getElementPositionLeft = function(locator) {
2037
- /**
2038
- * Retrieves the horizontal position of an element
2039
- *
2040
- * @param locator an <a href="#locators">element locator</a> pointing to an element OR an element itself
2041
- * @return number of pixels from the edge of the frame.
2042
- */
2043
- var element;
2044
- if ("string"==typeof locator) {
2045
- element = this.browserbot.findElement(locator);
2046
- }
2047
- else {
2048
- element = locator;
2049
- }
2050
- var x = element.offsetLeft;
2051
- var elementParent = element.offsetParent;
2052
-
2053
- while (elementParent != null)
2054
- {
2055
- if(document.all)
2056
- {
2057
- if( (elementParent.tagName != "TABLE") && (elementParent.tagName != "BODY") )
2058
- {
2059
- x += elementParent.clientLeft;
2060
- }
2061
- }
2062
- else // Netscape/DOM
2063
- {
2064
- if(elementParent.tagName == "TABLE")
2065
- {
2066
- var parentBorder = parseInt(elementParent.border);
2067
- if(isNaN(parentBorder))
2068
- {
2069
- var parentFrame = elementParent.getAttribute('frame');
2070
- if(parentFrame != null)
2071
- {
2072
- x += 1;
2073
- }
2074
- }
2075
- else if(parentBorder > 0)
2076
- {
2077
- x += parentBorder;
2078
- }
2079
- }
2080
- }
2081
- x += elementParent.offsetLeft;
2082
- elementParent = elementParent.offsetParent;
2083
- }
2084
- return x;
2085
- };
2086
-
2087
- Selenium.prototype.getElementPositionTop = function(locator) {
2088
- /**
2089
- * Retrieves the vertical position of an element
2090
- *
2091
- * @param locator an <a href="#locators">element locator</a> pointing to an element OR an element itself
2092
- * @return number of pixels from the edge of the frame.
2093
- */
2094
- var element;
2095
- if ("string"==typeof locator) {
2096
- element = this.browserbot.findElement(locator);
2097
- }
2098
- else {
2099
- element = locator;
2100
- }
2101
-
2102
- var y = 0;
2103
-
2104
- while (element != null)
2105
- {
2106
- if(document.all)
2107
- {
2108
- if( (element.tagName != "TABLE") && (element.tagName != "BODY") )
2109
- {
2110
- y += element.clientTop;
2111
- }
2112
- }
2113
- else // Netscape/DOM
2114
- {
2115
- if(element.tagName == "TABLE")
2116
- {
2117
- var parentBorder = parseInt(element.border);
2118
- if(isNaN(parentBorder))
2119
- {
2120
- var parentFrame = element.getAttribute('frame');
2121
- if(parentFrame != null)
2122
- {
2123
- y += 1;
2124
- }
2125
- }
2126
- else if(parentBorder > 0)
2127
- {
2128
- y += parentBorder;
2129
- }
2130
- }
2131
- }
2132
- y += element.offsetTop;
2133
-
2134
- // Netscape can get confused in some cases, such that the height of the parent is smaller
2135
- // than that of the element (which it shouldn't really be). If this is the case, we need to
2136
- // exclude this element, since it will result in too large a 'top' return value.
2137
- if (element.offsetParent && element.offsetParent.offsetHeight && element.offsetParent.offsetHeight < element.offsetHeight)
2138
- {
2139
- // skip the parent that's too small
2140
- element = element.offsetParent.offsetParent;
2141
- }
2142
- else
2143
- {
2144
- // Next up...
2145
- element = element.offsetParent;
2146
- }
2147
- }
2148
- return y;
2149
- };
2150
-
2151
- Selenium.prototype.getElementWidth = function(locator) {
2152
- /**
2153
- * Retrieves the width of an element
2154
- *
2155
- * @param locator an <a href="#locators">element locator</a> pointing to an element
2156
- * @return number width of an element in pixels
2157
- */
2158
- var element = this.browserbot.findElement(locator);
2159
- return element.offsetWidth;
2160
- };
2161
-
2162
- Selenium.prototype.getElementHeight = function(locator) {
2163
- /**
2164
- * Retrieves the height of an element
2165
- *
2166
- * @param locator an <a href="#locators">element locator</a> pointing to an element
2167
- * @return number height of an element in pixels
2168
- */
2169
- var element = this.browserbot.findElement(locator);
2170
- return element.offsetHeight;
2171
- };
2172
-
2173
- Selenium.prototype.getCursorPosition = function(locator) {
2174
- /**
2175
- * Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers.
2176
- *
2177
- * <p>Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to
2178
- * return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as <a href="http://jira.openqa.org/browse/SEL-243">SEL-243</a>.</p>
2179
- * This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.
2180
- *
2181
- * @param locator an <a href="#locators">element locator</a> pointing to an input element or textarea
2182
- * @return number the numerical position of the cursor in the field
2183
- */
2184
- var element = this.browserbot.findElement(locator);
2185
- var doc = this.browserbot.getDocument();
2186
- var win = this.browserbot.getCurrentWindow();
2187
- if( doc.selection && !browserVersion.isOpera){
2188
- try {
2189
- var selectRange = doc.selection.createRange().duplicate();
2190
- var elementRange = element.createTextRange();
2191
- selectRange.move("character",0);
2192
- elementRange.move("character",0);
2193
- var inRange1 = selectRange.inRange(elementRange);
2194
- var inRange2 = elementRange.inRange(selectRange);
2195
- elementRange.setEndPoint("EndToEnd", selectRange);
2196
- } catch (e) {
2197
- Assert.fail("There is no cursor on this page!");
2198
- }
2199
- var answer = String(elementRange.text).replace(/\r/g,"").length;
2200
- return answer;
2201
- } else {
2202
- if (typeof(element.selectionStart) != "undefined") {
2203
- if (win.getSelection && typeof(win.getSelection().rangeCount) != undefined && win.getSelection().rangeCount == 0) {
2204
- Assert.fail("There is no cursor on this page!");
2205
- }
2206
- return element.selectionStart;
2207
- }
2208
- }
2209
- throw new Error("Couldn't detect cursor position on this browser!");
2210
- }
2211
-
2212
-
2213
- Selenium.prototype.getExpression = function(expression) {
2214
- /**
2215
- * Returns the specified expression.
2216
- *
2217
- * <p>This is useful because of JavaScript preprocessing.
2218
- * It is used to generate commands like assertExpression and waitForExpression.</p>
2219
- *
2220
- * @param expression the value to return
2221
- * @return string the value passed in
2222
- */
2223
- return expression;
2224
- }
2225
-
2226
- Selenium.prototype.getXpathCount = function(xpath) {
2227
- /**
2228
- * Returns the number of nodes that match the specified xpath, eg. "//table" would give
2229
- * the number of tables.
2230
- *
2231
- * @param xpath the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you.
2232
- * @return number the number of nodes that match the specified xpath
2233
- */
2234
- var result = this.browserbot.evaluateXPathCount(xpath, this.browserbot.getDocument());
2235
- return result;
2236
- }
2237
-
2238
- Selenium.prototype.doAssignId = function(locator, identifier) {
2239
- /**
2240
- * Temporarily sets the "id" attribute of the specified element, so you can locate it in the future
2241
- * using its ID rather than a slow/complicated XPath. This ID will disappear once the page is
2242
- * reloaded.
2243
- * @param locator an <a href="#locators">element locator</a> pointing to an element
2244
- * @param identifier a string to be used as the ID of the specified element
2245
- */
2246
- var element = this.browserbot.findElement(locator);
2247
- element.id = identifier;
2248
- }
2249
-
2250
- Selenium.prototype.doAllowNativeXpath = function(allow) {
2251
- /**
2252
- * Specifies whether Selenium should use the native in-browser implementation
2253
- * of XPath (if any native version is available); if you pass "false" to
2254
- * this function, we will always use our pure-JavaScript xpath library.
2255
- * Using the pure-JS xpath library can improve the consistency of xpath
2256
- * element locators between different browser vendors, but the pure-JS
2257
- * version is much slower than the native implementations.
2258
- * @param allow boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath
2259
- */
2260
- if ("false" == allow || "0" == allow) { // The strings "false" and "0" are true values in JS
2261
- allow = false;
2262
- }
2263
- this.browserbot.allowNativeXpath = allow;
2264
- }
2265
-
2266
- Selenium.prototype.doIgnoreAttributesWithoutValue = function(ignore) {
2267
- /**
2268
- * Specifies whether Selenium will ignore xpath attributes that have no
2269
- * value, i.e. are the empty string, when using the non-native xpath
2270
- * evaluation engine. You'd want to do this for performance reasons in IE.
2271
- * However, this could break certain xpaths, for example an xpath that looks
2272
- * for an attribute whose value is NOT the empty string.
2273
- *
2274
- * The hope is that such xpaths are relatively rare, but the user should
2275
- * have the option of using them. Note that this only influences xpath
2276
- * evaluation when using the ajaxslt engine (i.e. not "javascript-xpath").
2277
- *
2278
- * @param ignore boolean, true means we'll ignore attributes without value
2279
- * at the expense of xpath "correctness"; false means
2280
- * we'll sacrifice speed for correctness.
2281
- */
2282
- if ('false' == ignore || '0' == ignore) {
2283
- ignore = false;
2284
- }
2285
- this.browserbot.ignoreAttributesWithoutValue = ignore;
2286
- }
2287
-
2288
- Selenium.prototype.doWaitForCondition = function(script, timeout) {
2289
- /**
2290
- * Runs the specified JavaScript snippet repeatedly until it evaluates to "true".
2291
- * The snippet may have multiple lines, but only the result of the last line
2292
- * will be considered.
2293
- *
2294
- * <p>Note that, by default, the snippet will be run in the runner's test window, not in the window
2295
- * of your application. To get the window of your application, you can use
2296
- * the JavaScript snippet <code>selenium.browserbot.getCurrentWindow()</code>, and then
2297
- * run your JavaScript in there</p>
2298
- * @param script the JavaScript snippet to run
2299
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2300
- */
2301
-
2302
- return Selenium.decorateFunctionWithTimeout(function () {
2303
- var window = selenium.browserbot.getCurrentWindow();
2304
- return eval(script);
2305
- }, timeout);
2306
- };
2307
-
2308
- Selenium.prototype.doWaitForCondition.dontCheckAlertsAndConfirms = true;
2309
-
2310
- Selenium.prototype.doSetTimeout = function(timeout) {
2311
- /**
2312
- * Specifies the amount of time that Selenium will wait for actions to complete.
2313
- *
2314
- * <p>Actions that require waiting include "open" and the "waitFor*" actions.</p>
2315
- * The default timeout is 30 seconds.
2316
- * @param timeout a timeout in milliseconds, after which the action will return with an error
2317
- */
2318
- if (!timeout) {
2319
- timeout = Selenium.DEFAULT_TIMEOUT;
2320
- }
2321
- this.defaultTimeout = timeout;
2322
- }
2323
-
2324
- Selenium.prototype.doWaitForPageToLoad = function(timeout) {
2325
- /**
2326
- * Waits for a new page to load.
2327
- *
2328
- * <p>You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc.
2329
- * (which are only available in the JS API).</p>
2330
- *
2331
- * <p>Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded"
2332
- * flag when it first notices a page load. Running any other Selenium command after
2333
- * turns the flag to false. Hence, if you want to wait for a page to load, you must
2334
- * wait immediately after a Selenium command that caused a page-load.</p>
2335
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2336
- */
2337
- // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded
2338
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
2339
- return this.makePageLoadCondition(timeout);
2340
- }
2341
- };
2342
-
2343
- Selenium.prototype.doWaitForFrameToLoad = function(frameAddress, timeout) {
2344
- /**
2345
- * Waits for a new frame to load.
2346
- *
2347
- * <p>Selenium constantly keeps track of new pages and frames loading,
2348
- * and sets a "newPageLoaded" flag when it first notices a page load.</p>
2349
- *
2350
- * See waitForPageToLoad for more information.
2351
- *
2352
- * @param frameAddress FrameAddress from the server side
2353
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2354
- */
2355
- // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded
2356
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
2357
- return this.makePageLoadCondition(timeout);
2358
- }
2359
- };
2360
-
2361
- Selenium.prototype._isNewPageLoaded = function() {
2362
- return this.browserbot.isNewPageLoaded();
2363
- };
2364
-
2365
- Selenium.prototype.doWaitForPageToLoad.dontCheckAlertsAndConfirms = true;
2366
-
2367
- /**
2368
- * Evaluate a parameter, performing JavaScript evaluation and variable substitution.
2369
- * If the string matches the pattern "javascript{ ... }", evaluate the string between the braces.
2370
- */
2371
- Selenium.prototype.preprocessParameter = function(value) {
2372
- var match = value.match(/^javascript\{((.|\r?\n)+)\}$/);
2373
- if (match && match[1]) {
2374
- return eval(match[1]).toString();
2375
- }
2376
- return this.replaceVariables(value);
2377
- };
2378
-
2379
- /*
2380
- * Search through str and replace all variable references ${varName} with their
2381
- * value in storedVars.
2382
- */
2383
- Selenium.prototype.replaceVariables = function(str) {
2384
- var stringResult = str;
2385
-
2386
- // Find all of the matching variable references
2387
- var match = stringResult.match(/\$\{\w+\}/g);
2388
- if (!match) {
2389
- return stringResult;
2390
- }
2391
-
2392
- // For each match, lookup the variable value, and replace if found
2393
- for (var i = 0; match && i < match.length; i++) {
2394
- var variable = match[i]; // The replacement variable, with ${}
2395
- var name = variable.substring(2, variable.length - 1); // The replacement variable without ${}
2396
- var replacement = storedVars[name];
2397
- if (replacement != undefined) {
2398
- stringResult = stringResult.replace(variable, replacement);
2399
- }
2400
- }
2401
- return stringResult;
2402
- };
2403
-
2404
- Selenium.prototype.getCookie = function() {
2405
- /**
2406
- * Return all cookies of the current page under test.
2407
- *
2408
- * @return string all cookies of the current page under test
2409
- */
2410
- var doc = this.browserbot.getDocument();
2411
- return doc.cookie;
2412
- };
2413
-
2414
- Selenium.prototype.getCookieByName = function(name) {
2415
- /**
2416
- * Returns the value of the cookie with the specified name, or throws an error if the cookie is not present.
2417
- * @param name the name of the cookie
2418
- * @return string the value of the cookie
2419
- */
2420
- var v = this.browserbot.getCookieByName(name);
2421
- if (v === null) {
2422
- throw new SeleniumError("Cookie '"+name+"' was not found");
2423
- }
2424
- return v;
2425
- };
2426
-
2427
- Selenium.prototype.isCookiePresent = function(name) {
2428
- /**
2429
- * Returns true if a cookie with the specified name is present, or false otherwise.
2430
- * @param name the name of the cookie
2431
- * @return boolean true if a cookie with the specified name is present, or false otherwise.
2432
- */
2433
- var v = this.browserbot.getCookieByName(name);
2434
- var absent = (v === null);
2435
- return !absent;
2436
- }
2437
-
2438
- Selenium.prototype.doCreateCookie = function(nameValuePair, optionsString) {
2439
- /**
2440
- * Create a new cookie whose path and domain are same with those of current page
2441
- * under test, unless you specified a path for this cookie explicitly.
2442
- *
2443
- * @param nameValuePair name and value of the cookie in a format "name=value"
2444
- * @param optionsString options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'.
2445
- * the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit
2446
- * of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will
2447
- * usually fail.
2448
- */
2449
- var results = /[^\s=\[\]\(\),"\/\?@:;]+=[^\s=\[\]\(\),"\/\?@:;]*/.test(nameValuePair);
2450
- if (!results) {
2451
- throw new SeleniumError("Invalid parameter.");
2452
- }
2453
- var cookie = nameValuePair.trim();
2454
- results = /max_age=(\d+)/.exec(optionsString);
2455
- if (results) {
2456
- var expireDateInMilliseconds = (new Date()).getTime() + results[1] * 1000;
2457
- cookie += "; expires=" + new Date(expireDateInMilliseconds).toGMTString();
2458
- }
2459
- results = /path=([^\s,]+)[,]?/.exec(optionsString);
2460
- if (results) {
2461
- var path = results[1];
2462
- if (browserVersion.khtml) {
2463
- // Safari and conquerer don't like paths with / at the end
2464
- if ("/" != path) {
2465
- path = path.replace(/\/$/, "");
2466
- }
2467
- }
2468
- cookie += "; path=" + path;
2469
- }
2470
- results = /domain=([^\s,]+)[,]?/.exec(optionsString);
2471
- if (results) {
2472
- var domain = results[1];
2473
- cookie += "; domain=" + domain;
2474
- }
2475
- LOG.debug("Setting cookie to: " + cookie);
2476
- this.browserbot.getDocument().cookie = cookie;
2477
- }
2478
-
2479
- Selenium.prototype.doDeleteCookie = function(name,optionsString) {
2480
- /**
2481
- * Delete a named cookie with specified path and domain. Be careful; to delete a cookie, you
2482
- * need to delete it using the exact same path and domain that were used to create the cookie.
2483
- * If the path is wrong, or the domain is wrong, the cookie simply won't be deleted. Also
2484
- * note that specifying a domain that isn't a subset of the current domain will usually fail.
2485
- *
2486
- * Since there's no way to discover at runtime the original path and domain of a given cookie,
2487
- * we've added an option called 'recurse' to try all sub-domains of the current domain with
2488
- * all paths that are a subset of the current path. Beware; this option can be slow. In
2489
- * big-O notation, it operates in O(n*m) time, where n is the number of dots in the domain
2490
- * name and m is the number of slashes in the path.
2491
- *
2492
- * @param name the name of the cookie to be deleted
2493
- * @param optionsString options for the cookie. Currently supported options include 'path', 'domain'
2494
- * and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true".
2495
- * The order of options are irrelevant. Note that specifying a domain that isn't a subset of
2496
- * the current domain will usually fail.
2497
- */
2498
- // set the expire time of the cookie to be deleted to one minute before now.
2499
- var path = "";
2500
- var domain = "";
2501
- var recurse = false;
2502
- var matched = false;
2503
- results = /path=([^\s,]+)[,]?/.exec(optionsString);
2504
- if (results) {
2505
- matched = true;
2506
- path = results[1];
2507
- }
2508
- results = /domain=([^\s,]+)[,]?/.exec(optionsString);
2509
- if (results) {
2510
- matched = true;
2511
- domain = results[1];
2512
- }
2513
- results = /recurse=([^\s,]+)[,]?/.exec(optionsString);
2514
- if (results) {
2515
- matched = true;
2516
- recurse = results[1];
2517
- if ("false" == recurse) {
2518
- recurse = false;
2519
- }
2520
- }
2521
- // Treat the entire optionsString as a path (for backwards compatibility)
2522
- if (optionsString && !matched) {
2523
- LOG.warn("Using entire optionsString as a path; please change the argument to deleteCookie to use path="+optionsString);
2524
- path = optionsString;
2525
- }
2526
- if (browserVersion.khtml) {
2527
- // Safari and conquerer don't like paths with / at the end
2528
- if ("/" != path) {
2529
- path = path.replace(/\/$/, "");
2530
- }
2531
- }
2532
- path = path.trim();
2533
- domain = domain.trim();
2534
- var cookieName = name.trim();
2535
- if (recurse) {
2536
- this.browserbot.recursivelyDeleteCookie(cookieName, domain, path);
2537
- } else {
2538
- this.browserbot.deleteCookie(cookieName, domain, path);
2539
- }
2540
- }
2541
-
2542
- Selenium.prototype.doDeleteAllVisibleCookies = function() {
2543
- /** Calls deleteCookie with recurse=true on all cookies visible to the current page.
2544
- * As noted on the documentation for deleteCookie, recurse=true can be much slower
2545
- * than simply deleting the cookies using a known domain/path.
2546
- */
2547
- var win = this.browserbot.getCurrentWindow();
2548
- var doc = win.document;
2549
- var cookieNames = this.browserbot.getAllCookieNames(doc);
2550
- var domain = doc.domain;
2551
- var path = win.location.pathname;
2552
- for (var i = 0; i < cookieNames.length; i++) {
2553
- this.browserbot.recursivelyDeleteCookie(cookieNames[i], domain, path, win);
2554
- }
2555
- }
2556
-
2557
- Selenium.prototype.doSetBrowserLogLevel = function(logLevel) {
2558
- /**
2559
- * Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded.
2560
- * Valid logLevel strings are: "debug", "info", "warn", "error" or "off".
2561
- * To see the browser logs, you need to
2562
- * either show the log window in GUI mode, or enable browser-side logging in Selenium RC.
2563
- *
2564
- * @param logLevel one of the following: "debug", "info", "warn", "error" or "off"
2565
- */
2566
- if (logLevel == null || logLevel == "") {
2567
- throw new SeleniumError("You must specify a log level");
2568
- }
2569
- logLevel = logLevel.toLowerCase();
2570
- if (LOG.logLevels[logLevel] == null) {
2571
- throw new SeleniumError("Invalid log level: " + logLevel);
2572
- }
2573
- LOG.setLogLevelThreshold(logLevel);
2574
- }
2575
-
2576
- Selenium.prototype.doRunScript = function(script) {
2577
- /**
2578
- * Creates a new "script" tag in the body of the current test window, and
2579
- * adds the specified text into the body of the command. Scripts run in
2580
- * this way can often be debugged more easily than scripts executed using
2581
- * Selenium's "getEval" command. Beware that JS exceptions thrown in these script
2582
- * tags aren't managed by Selenium, so you should probably wrap your script
2583
- * in try/catch blocks if there is any chance that the script will throw
2584
- * an exception.
2585
- * @param script the JavaScript snippet to run
2586
- */
2587
- var win = this.browserbot.getCurrentWindow();
2588
- var doc = win.document;
2589
- var scriptTag = doc.createElement("script");
2590
- scriptTag.type = "text/javascript"
2591
- scriptTag.text = script;
2592
- doc.body.appendChild(scriptTag);
2593
- }
2594
-
2595
- Selenium.prototype.doAddLocationStrategy = function(strategyName, functionDefinition) {
2596
- /**
2597
- * Defines a new function for Selenium to locate elements on the page.
2598
- * For example,
2599
- * if you define the strategy "foo", and someone runs click("foo=blah"), we'll
2600
- * run your function, passing you the string "blah", and click on the element
2601
- * that your function
2602
- * returns, or throw an "Element not found" error if your function returns null.
2603
- *
2604
- * We'll pass three arguments to your function:
2605
- * <ul>
2606
- * <li>locator: the string the user passed in</li>
2607
- * <li>inWindow: the currently selected window</li>
2608
- * <li>inDocument: the currently selected document</li>
2609
- * </ul>
2610
- * The function must return null if the element can't be found.
2611
- *
2612
- * @param strategyName the name of the strategy to define; this should use only
2613
- * letters [a-zA-Z] with no spaces or other punctuation.
2614
- * @param functionDefinition a string defining the body of a function in JavaScript.
2615
- * For example: <code>return inDocument.getElementById(locator);</code>
2616
- */
2617
- if (!/^[a-zA-Z]+$/.test(strategyName)) {
2618
- throw new SeleniumError("Invalid strategy name: " + strategyName);
2619
- }
2620
- var strategyFunction;
2621
- try {
2622
- strategyFunction = new Function("locator", "inDocument", "inWindow", functionDefinition);
2623
- } catch (ex) {
2624
- throw new SeleniumError("Error evaluating function definition: " + extractExceptionMessage(ex));
2625
- }
2626
- var safeStrategyFunction = function() {
2627
- try {
2628
- return strategyFunction.apply(this, arguments);
2629
- } catch (ex) {
2630
- throw new SeleniumError("Error executing strategy function " + strategyName + ": " + extractExceptionMessage(ex));
2631
- }
2632
- }
2633
- this.browserbot.locationStrategies[strategyName] = safeStrategyFunction;
2634
- }
2635
-
2636
- Selenium.prototype.doCaptureEntirePageScreenshot = function(filename, kwargs) {
2637
- /**
2638
- * Saves the entire contents of the current window canvas to a PNG file.
2639
- * Contrast this with the captureScreenshot command, which captures the
2640
- * contents of the OS viewport (i.e. whatever is currently being displayed
2641
- * on the monitor), and is implemented in the RC only. Currently this only
2642
- * works in Firefox when running in chrome mode, and in IE non-HTA using
2643
- * the EXPERIMENTAL "Snapsie" utility. The Firefox implementation is mostly
2644
- * borrowed from the Screengrab! Firefox extension. Please see
2645
- * http://www.screengrab.org and http://snapsie.sourceforge.net/ for
2646
- * details.
2647
- *
2648
- * @param filename the path to the file to persist the screenshot as. No
2649
- * filename extension will be appended by default.
2650
- * Directories will not be created if they do not exist,
2651
- * and an exception will be thrown, possibly by native
2652
- * code.
2653
- * @param kwargs a kwargs string that modifies the way the screenshot
2654
- * is captured. Example: "background=#CCFFDD" .
2655
- * Currently valid options:
2656
- * <dl>
2657
- * <dt>background</dt>
2658
- * <dd>the background CSS for the HTML document. This
2659
- * may be useful to set for capturing screenshots of
2660
- * less-than-ideal layouts, for example where absolute
2661
- * positioning causes the calculation of the canvas
2662
- * dimension to fail and a black background is exposed
2663
- * (possibly obscuring black text).</dd>
2664
- * </dl>
2665
- */
2666
- if (! browserVersion.isChrome &&
2667
- ! (browserVersion.isIE && ! browserVersion.isHTA)) {
2668
- throw new SeleniumError('captureEntirePageScreenshot is only '
2669
- + 'implemented for Firefox ("firefox" or "chrome", NOT '
2670
- + '"firefoxproxy") and IE non-HTA ("iexploreproxy", NOT "iexplore" '
2671
- + 'or "iehta"). The current browser isn\'t one of them!');
2672
- }
2673
-
2674
- // do or do not ... there is no try
2675
-
2676
- if (browserVersion.isIE) {
2677
- // targeting snapsIE >= 0.2
2678
- function getFailureMessage(exceptionMessage) {
2679
- var msg = 'Snapsie failed: ';
2680
- if (exceptionMessage) {
2681
- if (exceptionMessage ==
2682
- "Automation server can't create object") {
2683
- msg += 'Is it installed? Does it have permission to run '
2684
- 'as an add-on? See http://snapsie.sourceforge.net/';
2685
- }
2686
- else {
2687
- msg += exceptionMessage;
2688
- }
2689
- }
2690
- else {
2691
- msg += 'Undocumented error';
2692
- }
2693
- return msg;
2694
- }
2695
-
2696
- if (typeof(runOptions) != 'undefined' &&
2697
- runOptions.isMultiWindowMode() == false) {
2698
- // framed mode
2699
- try {
2700
- new Snapsie().saveSnapshot(filename, 'selenium_myiframe');
2701
- }
2702
- catch (e) {
2703
- throw new SeleniumError(getFailureMessage(e.message));
2704
- }
2705
- }
2706
- else {
2707
- // multi-window mode
2708
- if (!this.snapsieSrc) {
2709
- // XXX - cache snapsie, and capture the screenshot as a
2710
- // callback. Definitely a hack, because we may be late taking
2711
- // the first screenshot, but saves us from polluting other code
2712
- // for now. I wish there were an easier way to get at the
2713
- // contents of a referenced script!
2714
- var snapsieUrl = (this.browserbot.buttonWindow.location.href)
2715
- .replace(/(Test|Remote)Runner\.html/, 'lib/snapsie.js');
2716
- var self = this;
2717
- new Ajax.Request(snapsieUrl, {
2718
- method: 'get'
2719
- , onSuccess: function(transport) {
2720
- self.snapsieSrc = transport.responseText;
2721
- self.doCaptureEntirePageScreenshot(filename, kwargs);
2722
- }
2723
- });
2724
- return;
2725
- }
2726
-
2727
- // it's going into a string, so escape the backslashes
2728
- filename = filename.replace(/\\/g, '\\\\');
2729
-
2730
- // this is sort of hackish. We insert a script into the document,
2731
- // and remove it before anyone notices.
2732
- var doc = selenium.browserbot.getDocument();
2733
- var script = doc.createElement('script');
2734
- var scriptContent = this.snapsieSrc
2735
- + 'try {'
2736
- + ' new Snapsie().saveSnapshot("' + filename + '");'
2737
- + '}'
2738
- + 'catch (e) {'
2739
- + ' document.getElementById("takeScreenshot").failure ='
2740
- + ' e.message;'
2741
- + '}';
2742
- script.id = 'takeScreenshot';
2743
- script.language = 'javascript';
2744
- script.text = scriptContent;
2745
- doc.body.appendChild(script);
2746
- script.parentNode.removeChild(script);
2747
- if (script.failure) {
2748
- throw new SeleniumError(getFailureMessage(script.failure));
2749
- }
2750
- }
2751
- return;
2752
- }
2753
-
2754
- var grabber = {
2755
- prepareCanvas: function(width, height) {
2756
- var styleWidth = width + 'px';
2757
- var styleHeight = height + 'px';
2758
-
2759
- var grabCanvas = document.getElementById('screenshot_canvas');
2760
- if (!grabCanvas) {
2761
- // create the canvas
2762
- var ns = 'http://www.w3.org/1999/xhtml';
2763
- grabCanvas = document.createElementNS(ns, 'html:canvas');
2764
- grabCanvas.id = 'screenshot_canvas';
2765
- grabCanvas.style.display = 'none';
2766
- document.documentElement.appendChild(grabCanvas);
2767
- }
2768
-
2769
- grabCanvas.width = width;
2770
- grabCanvas.style.width = styleWidth;
2771
- grabCanvas.style.maxWidth = styleWidth;
2772
- grabCanvas.height = height;
2773
- grabCanvas.style.height = styleHeight;
2774
- grabCanvas.style.maxHeight = styleHeight;
2775
-
2776
- return grabCanvas;
2777
- },
2778
-
2779
- prepareContext: function(canvas, box) {
2780
- var context = canvas.getContext('2d');
2781
- context.clearRect(box.x, box.y, box.width, box.height);
2782
- context.save();
2783
- return context;
2784
- }
2785
- };
2786
-
2787
- var SGNsUtils = {
2788
- dataUrlToBinaryInputStream: function(dataUrl) {
2789
- var nsIoService = Components.classes["@mozilla.org/network/io-service;1"]
2790
- .getService(Components.interfaces.nsIIOService);
2791
- var channel = nsIoService
2792
- .newChannelFromURI(nsIoService.newURI(dataUrl, null, null));
2793
- var binaryInputStream = Components.classes["@mozilla.org/binaryinputstream;1"]
2794
- .createInstance(Components.interfaces.nsIBinaryInputStream);
2795
-
2796
- binaryInputStream.setInputStream(channel.open());
2797
- return binaryInputStream;
2798
- },
2799
-
2800
- newFileOutputStream: function(nsFile) {
2801
- var writeFlag = 0x02; // write only
2802
- var createFlag = 0x08; // create
2803
- var truncateFlag = 0x20; // truncate
2804
- var fileOutputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
2805
- .createInstance(Components.interfaces.nsIFileOutputStream);
2806
-
2807
- fileOutputStream.init(nsFile,
2808
- writeFlag | createFlag | truncateFlag, 0664, null);
2809
- return fileOutputStream;
2810
- },
2811
-
2812
- writeBinaryInputStreamToFileOutputStream:
2813
- function(binaryInputStream, fileOutputStream) {
2814
- var numBytes = binaryInputStream.available();
2815
- var bytes = binaryInputStream.readBytes(numBytes);
2816
- fileOutputStream.write(bytes, numBytes);
2817
- }
2818
- };
2819
-
2820
- // compute dimensions
2821
- var window = this.browserbot.getCurrentWindow();
2822
- var doc = window.document.documentElement;
2823
- var box = {
2824
- x: 0,
2825
- y: 0,
2826
- width: doc.scrollWidth,
2827
- height: doc.scrollHeight
2828
- };
2829
- LOG.debug('computed dimensions');
2830
-
2831
- var originalBackground = doc.style.background;
2832
-
2833
- if (kwargs) {
2834
- var args = parse_kwargs(kwargs);
2835
- if (args.background) {
2836
- doc.style.background = args.background;
2837
- }
2838
- }
2839
-
2840
- // grab
2841
- var format = 'png';
2842
- var canvas = grabber.prepareCanvas(box.width, box.height);
2843
- var context = grabber.prepareContext(canvas, box);
2844
- context.drawWindow(window, box.x, box.y, box.width, box.height,
2845
- 'rgb(0, 0, 0)');
2846
- context.restore();
2847
- var dataUrl = canvas.toDataURL("image/" + format);
2848
- LOG.debug('grabbed to canvas');
2849
-
2850
- doc.style.background = originalBackground;
2851
-
2852
- // save to file
2853
- var nsFile = Components.classes["@mozilla.org/file/local;1"]
2854
- .createInstance(Components.interfaces.nsILocalFile);
2855
- try {
2856
- nsFile.initWithPath(filename);
2857
- }
2858
- catch (e) {
2859
- if (/NS_ERROR_FILE_UNRECOGNIZED_PATH/.test(e.message)) {
2860
- // try using the opposite file separator
2861
- if (filename.indexOf('/') != -1) {
2862
- filename = filename.replace(/\//g, '\\');
2863
- }
2864
- else {
2865
- filename = filename.replace(/\\/g, '/');
2866
- }
2867
- nsFile.initWithPath(filename);
2868
- }
2869
- else {
2870
- throw e;
2871
- }
2872
- }
2873
- var binaryInputStream = SGNsUtils.dataUrlToBinaryInputStream(dataUrl);
2874
- var fileOutputStream = SGNsUtils.newFileOutputStream(nsFile);
2875
- SGNsUtils.writeBinaryInputStreamToFileOutputStream(binaryInputStream,
2876
- fileOutputStream);
2877
- fileOutputStream.close();
2878
- LOG.debug('saved to file');
2879
- };
2880
-
2881
- Selenium.prototype.doRollup = function(rollupName, kwargs) {
2882
- /**
2883
- * Executes a command rollup, which is a series of commands with a unique
2884
- * name, and optionally arguments that control the generation of the set of
2885
- * commands. If any one of the rolled-up commands fails, the rollup is
2886
- * considered to have failed. Rollups may also contain nested rollups.
2887
- *
2888
- * @param rollupName the name of the rollup command
2889
- * @param kwargs keyword arguments string that influences how the
2890
- * rollup expands into commands
2891
- */
2892
- // we have to temporarily hijack the commandStarted, nextCommand(),
2893
- // commandComplete(), and commandError() methods of the TestLoop object.
2894
- // When the expanded rollup commands are done executing (or an error has
2895
- // occurred), we'll restore them to their original values.
2896
- var loop = currentTest || htmlTestRunner.currentTest;
2897
- var backupManager = {
2898
- backup: function() {
2899
- for (var item in this.data) {
2900
- this.data[item] = loop[item];
2901
- }
2902
- }
2903
- , restore: function() {
2904
- for (var item in this.data) {
2905
- loop[item] = this.data[item];
2906
- }
2907
- }
2908
- , data: {
2909
- requiresCallBack: null
2910
- , commandStarted: null
2911
- , nextCommand: null
2912
- , commandComplete: null
2913
- , commandError: null
2914
- , pendingRollupCommands: null
2915
- , rollupFailed: null
2916
- , rollupFailedMessage: null
2917
- }
2918
- };
2919
-
2920
- var rule = RollupManager.getInstance().getRollupRule(rollupName);
2921
- var expandedCommands = rule.getExpandedCommands(kwargs);
2922
-
2923
- // hold your breath ...
2924
- try {
2925
- backupManager.backup();
2926
- loop.requiresCallBack = false;
2927
- loop.commandStarted = function() {};
2928
- loop.nextCommand = function() {
2929
- if (this.pendingRollupCommands.length == 0) {
2930
- return null;
2931
- }
2932
- var command = this.pendingRollupCommands.shift();
2933
- return command;
2934
- };
2935
- loop.commandComplete = function(result) {
2936
- if (result.failed) {
2937
- this.rollupFailed = true;
2938
- this.rollupFailureMessages.push(result.failureMessage);
2939
- }
2940
-
2941
- if (this.pendingRollupCommands.length == 0) {
2942
- result = {
2943
- failed: this.rollupFailed
2944
- , failureMessage: this.rollupFailureMessages.join('; ')
2945
- };
2946
- LOG.info('Rollup execution complete: ' + (result.failed
2947
- ? 'failed! (see error messages below)' : 'ok'));
2948
- backupManager.restore();
2949
- this.commandComplete(result);
2950
- }
2951
- };
2952
- loop.commandError = function(errorMessage) {
2953
- LOG.info('Rollup execution complete: bombed!');
2954
- backupManager.restore();
2955
- this.commandError(errorMessage);
2956
- };
2957
-
2958
- loop.pendingRollupCommands = expandedCommands;
2959
- loop.rollupFailed = false;
2960
- loop.rollupFailureMessages = [];
2961
- }
2962
- catch (e) {
2963
- LOG.error('Rollup error: ' + e);
2964
- backupManager.restore();
2965
- }
2966
- };
2967
-
2968
- Selenium.prototype.doAddScript = function(scriptContent, scriptTagId) {
2969
- /**
2970
- * Loads script content into a new script tag in the Selenium document. This
2971
- * differs from the runScript command in that runScript adds the script tag
2972
- * to the document of the AUT, not the Selenium document. The following
2973
- * entities in the script content are replaced by the characters they
2974
- * represent:
2975
- *
2976
- * &lt;
2977
- * &gt;
2978
- * &amp;
2979
- *
2980
- * The corresponding remove command is removeScript.
2981
- *
2982
- * @param scriptContent the Javascript content of the script to add
2983
- * @param scriptTagId (optional) the id of the new script tag. If
2984
- * specified, and an element with this id already
2985
- * exists, this operation will fail.
2986
- */
2987
- if (scriptTagId && document.getElementById(scriptTagId)) {
2988
- var msg = "Element with id '" + scriptTagId + "' already exists!";
2989
- throw new SeleniumError(msg);
2990
- }
2991
-
2992
- var head = document.getElementsByTagName('head')[0];
2993
- var script = document.createElement('script');
2994
-
2995
- script.type = 'text/javascript';
2996
-
2997
- if (scriptTagId) {
2998
- script.id = scriptTagId;
2999
- }
3000
-
3001
- // replace some entities
3002
- scriptContent = scriptContent
3003
- .replace(/&lt;/g, '<')
3004
- .replace(/&gt;/g, '>')
3005
- .replace(/&amp;/g, '&');
3006
-
3007
- script.text = scriptContent;
3008
- head.appendChild(script);
3009
- };
3010
-
3011
- Selenium.prototype.doRemoveScript = function(scriptTagId) {
3012
- /**
3013
- * Removes a script tag from the Selenium document identified by the given
3014
- * id. Does nothing if the referenced tag doesn't exist.
3015
- *
3016
- * @param scriptTagId the id of the script element to remove.
3017
- */
3018
- var script = document.getElementById(scriptTagId);
3019
-
3020
- if (script && getTagName(script) == 'script') {
3021
- script.parentNode.removeChild(script);
3022
- }
3023
- };
3024
-
3025
- Selenium.prototype.doUseXpathLibrary = function(libraryName) {
3026
- /**
3027
- * Allows choice of one of the available libraries.
3028
- * @param libraryName name of the desired library
3029
- * Only the following three can be chosen:
3030
- * ajaxslt - Google's library
3031
- * javascript - Cybozu Labs' faster library
3032
- * default - The default library. Currently the default library is ajaxslt.
3033
- * If libraryName isn't one of these three, then
3034
- * no change will be made.
3035
- *
3036
- */
3037
-
3038
- if (libraryName == "default") {
3039
- this.browserbot.xpathLibrary = this.browserbot.defaultXpathLibrary;
3040
- return;
3041
- }
3042
-
3043
- if ((libraryName != 'ajaxslt') && (libraryName != 'javascript-xpath')) {
3044
- return;
3045
- }
3046
-
3047
- this.browserbot.xpathLibrary = libraryName;
3048
-
3049
- };
3050
-
3051
- /**
3052
- * Factory for creating "Option Locators".
3053
- * An OptionLocator is an object for dealing with Select options (e.g. for
3054
- * finding a specified option, or asserting that the selected option of
3055
- * Select element matches some condition.
3056
- * The type of locator returned by the factory depends on the locator string:
3057
- * label=<exp> (OptionLocatorByLabel)
3058
- * value=<exp> (OptionLocatorByValue)
3059
- * index=<exp> (OptionLocatorByIndex)
3060
- * id=<exp> (OptionLocatorById)
3061
- * <exp> (default is OptionLocatorByLabel).
3062
- */
3063
- function OptionLocatorFactory() {
3064
- }
3065
-
3066
- OptionLocatorFactory.prototype.fromLocatorString = function(locatorString) {
3067
- var locatorType = 'label';
3068
- var locatorValue = locatorString;
3069
- // If there is a locator prefix, use the specified strategy
3070
- var result = locatorString.match(/^([a-zA-Z]+)=(.*)/);
3071
- if (result) {
3072
- locatorType = result[1];
3073
- locatorValue = result[2];
3074
- }
3075
- if (this.optionLocators == undefined) {
3076
- this.registerOptionLocators();
3077
- }
3078
- if (this.optionLocators[locatorType]) {
3079
- return new this.optionLocators[locatorType](locatorValue);
3080
- }
3081
- throw new SeleniumError("Unknown option locator type: " + locatorType);
3082
- };
3083
-
3084
- /**
3085
- * To allow for easy extension, all of the option locators are found by
3086
- * searching for all methods of OptionLocatorFactory.prototype that start
3087
- * with "OptionLocatorBy".
3088
- * TODO: Consider using the term "Option Specifier" instead of "Option Locator".
3089
- */
3090
- OptionLocatorFactory.prototype.registerOptionLocators = function() {
3091
- this.optionLocators={};
3092
- for (var functionName in this) {
3093
- var result = /OptionLocatorBy([A-Z].+)$/.exec(functionName);
3094
- if (result != null) {
3095
- var locatorName = result[1].lcfirst();
3096
- this.optionLocators[locatorName] = this[functionName];
3097
- }
3098
- }
3099
- };
3100
-
3101
- /**
3102
- * OptionLocator for options identified by their labels.
3103
- */
3104
- OptionLocatorFactory.prototype.OptionLocatorByLabel = function(label) {
3105
- this.label = label;
3106
- this.labelMatcher = new PatternMatcher(this.label);
3107
- this.findOption = function(element) {
3108
- for (var i = 0; i < element.options.length; i++) {
3109
- if (this.labelMatcher.matches(element.options[i].text)) {
3110
- return element.options[i];
3111
- }
3112
- }
3113
- throw new SeleniumError("Option with label '" + this.label + "' not found");
3114
- };
3115
-
3116
- this.assertSelected = function(element) {
3117
- var selectedLabel = element.options[element.selectedIndex].text;
3118
- Assert.matches(this.label, selectedLabel)
3119
- };
3120
- };
3121
-
3122
- /**
3123
- * OptionLocator for options identified by their values.
3124
- */
3125
- OptionLocatorFactory.prototype.OptionLocatorByValue = function(value) {
3126
- this.value = value;
3127
- this.valueMatcher = new PatternMatcher(this.value);
3128
- this.findOption = function(element) {
3129
- for (var i = 0; i < element.options.length; i++) {
3130
- if (this.valueMatcher.matches(element.options[i].value)) {
3131
- return element.options[i];
3132
- }
3133
- }
3134
- throw new SeleniumError("Option with value '" + this.value + "' not found");
3135
- };
3136
-
3137
- this.assertSelected = function(element) {
3138
- var selectedValue = element.options[element.selectedIndex].value;
3139
- Assert.matches(this.value, selectedValue)
3140
- };
3141
- };
3142
-
3143
- /**
3144
- * OptionLocator for options identified by their index.
3145
- */
3146
- OptionLocatorFactory.prototype.OptionLocatorByIndex = function(index) {
3147
- this.index = Number(index);
3148
- if (isNaN(this.index) || this.index < 0) {
3149
- throw new SeleniumError("Illegal Index: " + index);
3150
- }
3151
-
3152
- this.findOption = function(element) {
3153
- if (element.options.length <= this.index) {
3154
- throw new SeleniumError("Index out of range. Only " + element.options.length + " options available");
3155
- }
3156
- return element.options[this.index];
3157
- };
3158
-
3159
- this.assertSelected = function(element) {
3160
- Assert.equals(this.index, element.selectedIndex);
3161
- };
3162
- };
3163
-
3164
- /**
3165
- * OptionLocator for options identified by their id.
3166
- */
3167
- OptionLocatorFactory.prototype.OptionLocatorById = function(id) {
3168
- this.id = id;
3169
- this.idMatcher = new PatternMatcher(this.id);
3170
- this.findOption = function(element) {
3171
- for (var i = 0; i < element.options.length; i++) {
3172
- if (this.idMatcher.matches(element.options[i].id)) {
3173
- return element.options[i];
3174
- }
3175
- }
3176
- throw new SeleniumError("Option with id '" + this.id + "' not found");
3177
- };
3178
-
3179
- this.assertSelected = function(element) {
3180
- var selectedId = element.options[element.selectedIndex].id;
3181
- Assert.matches(this.id, selectedId)
3182
- };
3183
- };
3184
-