browsercms 3.1.5 → 3.3.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (425) hide show
  1. data/app/controllers/cms/base_controller.rb +3 -3
  2. data/app/controllers/cms/content_block_controller.rb +2 -2
  3. data/app/controllers/cms/content_controller.rb +5 -4
  4. data/app/controllers/cms/error_handling.rb +1 -1
  5. data/app/controllers/cms/routes_controller.rb +4 -5
  6. data/app/controllers/cms/section_nodes_controller.rb +1 -6
  7. data/app/controllers/cms/sections_controller.rb +2 -3
  8. data/app/controllers/cms/tasks_controller.rb +3 -0
  9. data/app/controllers/cms/users_controller.rb +1 -1
  10. data/app/helpers/cms/application_helper.rb +137 -34
  11. data/app/helpers/cms/form_builder.rb +33 -21
  12. data/app/helpers/cms/page_helper.rb +43 -10
  13. data/app/helpers/cms/path_helper.rb +1 -1
  14. data/app/helpers/cms/rendering_helper.rb +3 -4
  15. data/app/helpers/cms/section_nodes_helper.rb +5 -43
  16. data/app/models/abstract_file_block.rb +1 -16
  17. data/app/models/attachment.rb +57 -22
  18. data/app/models/category.rb +4 -4
  19. data/app/models/category_type.rb +2 -2
  20. data/app/models/cms/view_context.rb +46 -0
  21. data/app/models/connector.rb +7 -6
  22. data/app/models/content_type.rb +3 -3
  23. data/app/models/dynamic_view.rb +1 -1
  24. data/app/models/email_message.rb +2 -2
  25. data/app/models/file_block.rb +12 -0
  26. data/app/models/group.rb +4 -4
  27. data/app/models/group_type.rb +4 -4
  28. data/app/models/html_block.rb +1 -1
  29. data/app/models/image_block.rb +12 -0
  30. data/app/models/link.rb +22 -5
  31. data/app/models/page.rb +87 -46
  32. data/app/models/page_route.rb +61 -6
  33. data/app/models/permission.rb +1 -1
  34. data/app/models/portlet.rb +14 -4
  35. data/app/models/section.rb +48 -86
  36. data/app/models/section_node.rb +25 -40
  37. data/app/models/site.rb +1 -1
  38. data/app/models/tag.rb +1 -1
  39. data/app/models/task.rb +8 -7
  40. data/app/models/user.rb +2 -7
  41. data/app/portlets/forgot_password_portlet.rb +6 -2
  42. data/app/portlets/reset_password_portlet.rb +1 -1
  43. data/app/views/cms/blocks/_toolbar.html.erb +1 -1
  44. data/app/views/cms/blocks/_toolbar_for_collection.html.erb +3 -6
  45. data/app/views/cms/blocks/_toolbar_for_member.html.erb +3 -5
  46. data/app/views/cms/blocks/edit.html.erb +4 -4
  47. data/app/views/cms/blocks/index.html.erb +7 -7
  48. data/app/views/cms/blocks/new.html.erb +4 -4
  49. data/app/views/cms/blocks/show.html.erb +2 -2
  50. data/app/views/cms/blocks/usages.html.erb +2 -2
  51. data/app/views/cms/blocks/versions.html.erb +4 -4
  52. data/app/views/cms/cache/show.html.erb +2 -2
  53. data/app/views/cms/categories/_form.html.erb +2 -2
  54. data/app/views/cms/connectors/new.html.erb +6 -8
  55. data/app/views/cms/content/no_page.html.erb +1 -1
  56. data/app/views/cms/content/show.html.erb +2 -7
  57. data/app/views/cms/dashboard/_page_drafts.html.erb +1 -1
  58. data/app/views/cms/dashboard/_tasks.html.erb +1 -1
  59. data/app/views/cms/dashboard/index.html.erb +1 -1
  60. data/app/views/cms/dynamic_views/_form.html.erb +2 -2
  61. data/app/views/cms/dynamic_views/index.html.erb +7 -10
  62. data/app/views/cms/email_messages/show.html.erb +2 -2
  63. data/app/views/cms/file_blocks/_form.html.erb +4 -4
  64. data/app/views/cms/form_builder/_cms_fancy_drop_down.html.erb +2 -2
  65. data/app/views/cms/form_builder/_cms_file_field.html.erb +2 -2
  66. data/app/views/cms/form_builder/_cms_tag_list.html.erb +2 -2
  67. data/app/views/cms/form_builder/_cms_text_editor.html.erb +2 -2
  68. data/app/views/cms/groups/_form.html.erb +5 -5
  69. data/app/views/cms/groups/_permissions.html.erb +4 -4
  70. data/app/views/cms/groups/_sections.html.erb +1 -2
  71. data/app/views/cms/groups/index.html.erb +1 -1
  72. data/app/views/cms/html_blocks/render.html.erb +1 -1
  73. data/app/views/cms/image_blocks/_form.html.erb +4 -5
  74. data/app/views/cms/links/_form.html.erb +1 -1
  75. data/app/views/cms/links/edit.html.erb +2 -2
  76. data/app/views/cms/links/new.html.erb +2 -2
  77. data/app/views/cms/page_routes/_form.html.erb +2 -2
  78. data/app/views/cms/page_routes/index.html.erb +6 -9
  79. data/app/views/cms/page_routes/show.html.erb +5 -8
  80. data/app/views/cms/pages/_edit_connector.html.erb +1 -1
  81. data/app/views/cms/pages/_form.html.erb +3 -3
  82. data/app/views/cms/pages/edit.html.erb +2 -2
  83. data/app/views/cms/pages/new.html.erb +7 -7
  84. data/app/views/cms/pages/versions.html.erb +4 -4
  85. data/app/views/cms/redirects/_form.html.erb +2 -2
  86. data/app/views/cms/redirects/index.html.erb +8 -7
  87. data/app/views/cms/routes/index.html.erb +2 -2
  88. data/app/views/cms/section_nodes/_link.html.erb +3 -6
  89. data/app/views/cms/section_nodes/_node.html.erb +4 -13
  90. data/app/views/cms/section_nodes/_page.html.erb +7 -13
  91. data/app/views/cms/section_nodes/_section.html.erb +8 -24
  92. data/app/views/cms/section_nodes/_section_node.html.erb +10 -0
  93. data/app/views/cms/section_nodes/index.html.erb +18 -30
  94. data/app/views/cms/sections/_form.html.erb +4 -6
  95. data/app/views/cms/sections/edit.html.erb +2 -2
  96. data/app/views/cms/sections/index.html.erb +3 -3
  97. data/app/views/cms/sections/new.html.erb +3 -3
  98. data/app/views/cms/sessions/new.html.erb +3 -3
  99. data/app/views/cms/shared/_pagination.html.erb +1 -1
  100. data/app/views/cms/shared/error.html.erb +1 -1
  101. data/app/views/cms/tags/render.html.erb +2 -2
  102. data/app/views/cms/tasks/new.html.erb +4 -4
  103. data/app/views/cms/users/_form.html.erb +3 -3
  104. data/app/views/cms/users/_toolbar.html.erb +3 -3
  105. data/app/views/cms/users/change_password.html.erb +5 -5
  106. data/app/views/cms/users/edit.html.erb +2 -2
  107. data/app/views/cms/users/index.html.erb +4 -4
  108. data/app/views/cms/users/new.html.erb +2 -2
  109. data/app/views/cms/users/show.html.erb +16 -16
  110. data/app/views/layouts/_cms_toolbar.html.erb +5 -5
  111. data/app/views/layouts/_page_toolbar.html.erb +11 -11
  112. data/app/views/layouts/cms/_footer.erb +1 -1
  113. data/app/views/layouts/cms/_head.html.erb +2 -6
  114. data/app/views/layouts/cms/administration.html.erb +32 -32
  115. data/app/views/layouts/cms/content_library.html.erb +5 -5
  116. data/app/views/layouts/cms/toolbar.html.erb +1 -1
  117. data/app/views/portlets/email_page/render.html.erb +2 -2
  118. data/app/views/portlets/forgot_password/render.html.erb +1 -1
  119. data/app/views/portlets/login/render.html.erb +4 -2
  120. data/app/views/portlets/reset_password/render.html.erb +1 -1
  121. data/app/views/tests/pretend/open_with_layout.html.erb +1 -1
  122. data/bin/bcms +0 -0
  123. data/bin/bcms-upgrade +232 -0
  124. data/bin/browsercms +2 -2
  125. data/browsercms.gemspec +16 -14
  126. data/db/migrate/20100705083859_browsercms_3_3_0.rb +56 -0
  127. data/db/seeds.rb +58 -0
  128. data/doc/guides/html/authentication.html +448 -192
  129. data/doc/guides/html/build_it_yourself.html +454 -175
  130. data/doc/guides/html/building_modules.html +451 -220
  131. data/doc/guides/html/building_templates.html +448 -498
  132. data/doc/guides/html/content_blocks.html +450 -470
  133. data/doc/guides/html/customizing_browsercms.html +453 -169
  134. data/doc/guides/html/deployment_guide.html +443 -82
  135. data/doc/guides/html/files/bcmsorg.js +28 -0
  136. data/doc/guides/html/files/clearfix.css +8 -0
  137. data/doc/guides/html/files/cufon.js +7 -0
  138. data/doc/guides/html/files/global.css +190 -0
  139. data/doc/guides/html/files/helvetica.js +91 -0
  140. data/doc/guides/html/files/jquery.js +11 -0
  141. data/doc/guides/html/getting_started.html +454 -213
  142. data/doc/guides/html/index.html +454 -174
  143. data/doc/guides/html/installing_modules.html +454 -186
  144. data/doc/guides/html/portlets.html +451 -232
  145. data/doc/guides/html/user_guide.html +452 -270
  146. data/doc/guides/html/writing_guides.html +454 -161
  147. data/lib/acts_as_list.rb +1 -1
  148. data/lib/browsercms.rb +10 -6
  149. data/lib/cms/acts.rb +7 -0
  150. data/lib/cms/authentication.rb +4 -0
  151. data/lib/cms/authentication/controller.rb +1 -1
  152. data/lib/cms/behaviors.rb +1 -1
  153. data/lib/cms/behaviors/archiving.rb +2 -2
  154. data/lib/cms/behaviors/attaching.rb +28 -43
  155. data/lib/cms/behaviors/categorizing.rb +1 -1
  156. data/lib/cms/behaviors/connecting.rb +27 -12
  157. data/lib/cms/behaviors/dynamic_attributes.rb +8 -5
  158. data/lib/cms/behaviors/hiding.rb +2 -2
  159. data/lib/cms/behaviors/publishing.rb +32 -22
  160. data/lib/cms/behaviors/rendering.rb +41 -18
  161. data/lib/cms/behaviors/searching.rb +1 -1
  162. data/lib/cms/behaviors/soft_deleting.rb +58 -29
  163. data/lib/cms/behaviors/taggable.rb +1 -1
  164. data/lib/cms/behaviors/userstamping.rb +5 -4
  165. data/lib/cms/behaviors/versioning.rb +192 -111
  166. data/lib/cms/content_rendering_support.rb +3 -3
  167. data/lib/cms/date_picker.rb +23 -0
  168. data/lib/cms/engine.rb +46 -0
  169. data/lib/cms/extensions.rb +1 -1
  170. data/lib/cms/extensions/active_record/errors.rb +2 -2
  171. data/lib/cms/extensions/hash.rb +4 -2
  172. data/lib/cms/extensions/string.rb +7 -2
  173. data/lib/cms/init.rb +32 -21
  174. data/lib/cms/module.rb +22 -0
  175. data/lib/cms/module_installation.rb +38 -0
  176. data/lib/cms/routes.rb +127 -115
  177. data/lib/cms/version.rb +2 -2
  178. data/lib/generators/browser_cms.rb +12 -0
  179. data/lib/generators/browser_cms/cms/USAGE +2 -0
  180. data/lib/generators/browser_cms/cms/cms_generator.rb +36 -0
  181. data/{rails_generators/browser_cms → lib/generators/browser_cms/cms}/templates/README +0 -0
  182. data/{rails_generators/browser_cms_demo_site → lib/generators/browser_cms/demo_site}/USAGE +0 -0
  183. data/lib/generators/browser_cms/demo_site/demo_site_generator.rb +138 -0
  184. data/lib/generators/browser_cms/demo_site/templates/demo_site.rake +11 -0
  185. data/{rails_generators/browser_cms_demo_site/templates/migration.rb → lib/generators/browser_cms/demo_site/templates/migration.erb} +2 -8
  186. data/lib/generators/cms/content_block/USAGE +22 -0
  187. data/lib/generators/cms/content_block/content_block_generator.rb +55 -0
  188. data/{rails_generators → lib/generators/cms}/content_block/templates/_form.html.erb +0 -0
  189. data/{rails_generators → lib/generators/cms}/content_block/templates/content_block.rb +0 -0
  190. data/{rails_generators → lib/generators/cms}/content_block/templates/controller.rb +0 -0
  191. data/{rails_generators → lib/generators/cms}/content_block/templates/functional_test.erb +0 -0
  192. data/{rails_generators/content_block/templates/migration.rb → lib/generators/cms/content_block/templates/migration.erb} +1 -1
  193. data/{rails_generators → lib/generators/cms}/content_block/templates/render.html.erb +0 -0
  194. data/{rails_generators → lib/generators/cms}/content_block/templates/unit_test.erb +0 -0
  195. data/lib/generators/cms/install/USAGE +8 -0
  196. data/lib/generators/cms/install/install_generator.rb +20 -0
  197. data/{rails_generators → lib/generators/cms}/portlet/USAGE +3 -16
  198. data/lib/generators/cms/portlet/portlet_generator.rb +38 -0
  199. data/{rails_generators → lib/generators/cms}/portlet/templates/_form.html.erb +0 -0
  200. data/{rails_generators → lib/generators/cms}/portlet/templates/portlet.rb +0 -0
  201. data/{rails_generators → lib/generators/cms}/portlet/templates/portlet_helper.rb +0 -0
  202. data/{rails_generators → lib/generators/cms}/portlet/templates/render.html.erb +0 -0
  203. data/{rails_generators → lib/generators/cms}/portlet/templates/unit_test.erb +0 -0
  204. data/{rails_generators → lib/generators/cms}/template/USAGE +1 -1
  205. data/lib/generators/cms/template/template_generator.rb +18 -0
  206. data/lib/generators/cms/template/templates/template.erb +2 -0
  207. data/lib/generators/cms/upgrade_module/README.txt +3 -0
  208. data/lib/generators/cms/upgrade_module/templates/20100705083859_browsercms_3_3_0.rb +56 -0
  209. data/lib/generators/cms/upgrade_module/templates/README +1 -0
  210. data/lib/generators/cms/upgrade_module/templates/USAGE.erb +10 -0
  211. data/lib/generators/cms/upgrade_module/templates/build_gem.rake +5 -0
  212. data/lib/generators/cms/upgrade_module/templates/engine.erb +7 -0
  213. data/lib/generators/cms/upgrade_module/templates/gemspec.erb +25 -0
  214. data/lib/generators/cms/upgrade_module/templates/gitignore.erb +11 -0
  215. data/lib/generators/cms/upgrade_module/templates/install.erb +9 -0
  216. data/lib/generators/cms/upgrade_module/templates/module_file.erb +3 -0
  217. data/lib/generators/cms/upgrade_module/templates/routes.erb +7 -0
  218. data/lib/generators/cms/upgrade_module/upgrade_module_generator.rb +61 -0
  219. data/lib/tasks/build_gem.rake +1 -0
  220. data/lib/tasks/cms.rake +34 -6
  221. data/lib/tasks/cucumber.rake +53 -0
  222. data/lib/tasks/db.rake +2 -2
  223. data/public/javascripts/cms/application.js +144 -135
  224. data/public/javascripts/cms/sitemap.js +383 -357
  225. data/public/javascripts/jquery-ui.js +782 -591
  226. data/public/javascripts/jquery.cookie.js +38 -43
  227. data/public/javascripts/jquery.js +13 -8
  228. data/public/javascripts/jquery.taglist.js +7 -0
  229. data/public/stylesheets/cms/date_picker.css +49 -40
  230. data/rails/init.rb +2 -3
  231. data/templates/blank.rb +13 -7
  232. data/templates/demo.rb +15 -7
  233. data/templates/module.rb +12 -75
  234. metadata +87 -407
  235. data/app/helpers/cms/content_block_helper.rb +0 -27
  236. data/app/views/layouts/cms/thickbox.html.erb +0 -24
  237. data/db/migrate/20120117144039_browsercms315.rb +0 -94
  238. data/db/migrate/20121114172307_load_seeds.rb +0 -70
  239. data/lib/cms/addressable.rb +0 -83
  240. data/lib/cms/error_pages.rb +0 -8
  241. data/public/images/cms/thickbox/loadingAnimation.gif +0 -0
  242. data/public/images/cms/thickbox/macFFBgHack.png +0 -0
  243. data/public/javascripts/jquery.contextMenu.js +0 -211
  244. data/public/javascripts/jquery.dimensions.js +0 -119
  245. data/public/javascripts/jquery.thickbox.js +0 -10
  246. data/public/stylesheets/cms/jquery.contextMenu.css +0 -61
  247. data/public/stylesheets/cms/thickbox.css +0 -163
  248. data/rails_generators/browser_cms/USAGE +0 -2
  249. data/rails_generators/browser_cms/browser_cms_generator.rb +0 -35
  250. data/rails_generators/browser_cms_demo_site/browser_cms_demo_site_generator.rb +0 -63
  251. data/rails_generators/content_block/USAGE +0 -32
  252. data/rails_generators/content_block/content_block_generator.rb +0 -69
  253. data/rails_generators/portlet/portlet_generator.rb +0 -35
  254. data/rails_generators/template/template_generator.rb +0 -18
  255. data/rails_generators/template/templates/template.erb +0 -3
  256. data/test/custom_assertions.rb +0 -74
  257. data/test/factories.rb +0 -111
  258. data/test/factories/sitemap_factories.rb +0 -28
  259. data/test/fixtures/connectors.yml +0 -97
  260. data/test/fixtures/content_type_groups.yml +0 -13
  261. data/test/fixtures/content_types.yml +0 -50
  262. data/test/fixtures/dynamic_view_versions.yml +0 -26
  263. data/test/fixtures/dynamic_views.yml +0 -26
  264. data/test/fixtures/group_permissions.yml +0 -16
  265. data/test/fixtures/group_sections.yml +0 -31
  266. data/test/fixtures/group_type_permissions.yml +0 -11
  267. data/test/fixtures/group_types.yml +0 -25
  268. data/test/fixtures/groups.yml +0 -25
  269. data/test/fixtures/html_block_versions.yml +0 -67
  270. data/test/fixtures/html_blocks.yml +0 -63
  271. data/test/fixtures/page_versions.yml +0 -265
  272. data/test/fixtures/pages.yml +0 -85
  273. data/test/fixtures/permissions.yml +0 -28
  274. data/test/fixtures/section_nodes.yml +0 -46
  275. data/test/fixtures/sections.yml +0 -19
  276. data/test/fixtures/sites.yml +0 -9
  277. data/test/fixtures/user_group_memberships.yml +0 -11
  278. data/test/fixtures/users.yml +0 -15
  279. data/test/functional/cms/cache_controller_test.rb +0 -14
  280. data/test/functional/cms/categories_controller_test.rb +0 -25
  281. data/test/functional/cms/connectors_controller_test.rb +0 -60
  282. data/test/functional/cms/content_block_controller_test.rb +0 -120
  283. data/test/functional/cms/content_controller_test.rb +0 -439
  284. data/test/functional/cms/content_types_controller_test.rb +0 -18
  285. data/test/functional/cms/dashboard_controller_test.rb +0 -16
  286. data/test/functional/cms/dynamic_views_controller_test.rb +0 -52
  287. data/test/functional/cms/file_blocks_controller_test.rb +0 -52
  288. data/test/functional/cms/groups_controller_test.rb +0 -50
  289. data/test/functional/cms/home_controller_test.rb +0 -156
  290. data/test/functional/cms/html_blocks_controller_test.rb +0 -164
  291. data/test/functional/cms/image_blocks_controller_test.rb +0 -82
  292. data/test/functional/cms/links_controller_test.rb +0 -148
  293. data/test/functional/cms/pages_controller_test.rb +0 -227
  294. data/test/functional/cms/portlets_controller_test.rb +0 -67
  295. data/test/functional/cms/section_nodes_controller_test.rb +0 -112
  296. data/test/functional/cms/sections_controller_test.rb +0 -227
  297. data/test/functional/cms/sessions_controller_test.rb +0 -76
  298. data/test/functional/cms/toolbar_controller_test.rb +0 -64
  299. data/test/functional/cms/users_controller_test.rb +0 -231
  300. data/test/functional/tests/pretend_controller_test.rb +0 -57
  301. data/test/integration/cms/ckeditor_test.rb +0 -30
  302. data/test/integration/cms/password_management_test.rb +0 -56
  303. data/test/integration/login_test.rb +0 -14
  304. data/test/integration/sitemap_performance_test.rb +0 -26
  305. data/test/selenium-core/Blank.html +0 -7
  306. data/test/selenium-core/InjectedRemoteRunner.html +0 -8
  307. data/test/selenium-core/RemoteRunner.html +0 -110
  308. data/test/selenium-core/SeleniumLog.html +0 -109
  309. data/test/selenium-core/TestPrompt.html +0 -145
  310. data/test/selenium-core/TestRunner-splash.html +0 -55
  311. data/test/selenium-core/TestRunner.hta +0 -176
  312. data/test/selenium-core/TestRunner.html +0 -176
  313. data/test/selenium-core/domviewer/butmin.gif +0 -0
  314. data/test/selenium-core/domviewer/butplus.gif +0 -0
  315. data/test/selenium-core/domviewer/domviewer.css +0 -298
  316. data/test/selenium-core/domviewer/domviewer.html +0 -16
  317. data/test/selenium-core/domviewer/selenium-domviewer.js +0 -205
  318. data/test/selenium-core/icons/all.png +0 -0
  319. data/test/selenium-core/icons/continue.png +0 -0
  320. data/test/selenium-core/icons/continue_disabled.png +0 -0
  321. data/test/selenium-core/icons/pause.png +0 -0
  322. data/test/selenium-core/icons/pause_disabled.png +0 -0
  323. data/test/selenium-core/icons/selected.png +0 -0
  324. data/test/selenium-core/icons/step.png +0 -0
  325. data/test/selenium-core/icons/step_disabled.png +0 -0
  326. data/test/selenium-core/iedoc-core.xml +0 -1515
  327. data/test/selenium-core/iedoc.xml +0 -1469
  328. data/test/selenium-core/lib/cssQuery/cssQuery-p.js +0 -6
  329. data/test/selenium-core/lib/cssQuery/src/cssQuery-level2.js +0 -142
  330. data/test/selenium-core/lib/cssQuery/src/cssQuery-level3.js +0 -150
  331. data/test/selenium-core/lib/cssQuery/src/cssQuery-standard.js +0 -53
  332. data/test/selenium-core/lib/cssQuery/src/cssQuery.js +0 -356
  333. data/test/selenium-core/lib/prototype.js +0 -2006
  334. data/test/selenium-core/lib/scriptaculous/builder.js +0 -101
  335. data/test/selenium-core/lib/scriptaculous/controls.js +0 -815
  336. data/test/selenium-core/lib/scriptaculous/dragdrop.js +0 -915
  337. data/test/selenium-core/lib/scriptaculous/effects.js +0 -958
  338. data/test/selenium-core/lib/scriptaculous/scriptaculous.js +0 -47
  339. data/test/selenium-core/lib/scriptaculous/slider.js +0 -283
  340. data/test/selenium-core/lib/scriptaculous/unittest.js +0 -383
  341. data/test/selenium-core/scripts/find_matching_child.js +0 -69
  342. data/test/selenium-core/scripts/htmlutils.js +0 -894
  343. data/test/selenium-core/scripts/injection.html +0 -72
  344. data/test/selenium-core/scripts/js2html.js +0 -70
  345. data/test/selenium-core/scripts/narcissus-defs.js +0 -175
  346. data/test/selenium-core/scripts/narcissus-exec.js +0 -1054
  347. data/test/selenium-core/scripts/narcissus-parse.js +0 -1003
  348. data/test/selenium-core/scripts/se2html.js +0 -63
  349. data/test/selenium-core/scripts/selenium-api.js +0 -2409
  350. data/test/selenium-core/scripts/selenium-browserbot.js +0 -2203
  351. data/test/selenium-core/scripts/selenium-browserdetect.js +0 -150
  352. data/test/selenium-core/scripts/selenium-commandhandlers.js +0 -377
  353. data/test/selenium-core/scripts/selenium-executionloop.js +0 -175
  354. data/test/selenium-core/scripts/selenium-logging.js +0 -147
  355. data/test/selenium-core/scripts/selenium-remoterunner.js +0 -571
  356. data/test/selenium-core/scripts/selenium-testrunner.js +0 -1333
  357. data/test/selenium-core/scripts/selenium-version.js +0 -5
  358. data/test/selenium-core/scripts/user-extensions.js +0 -3
  359. data/test/selenium-core/scripts/user-extensions.js.sample +0 -75
  360. data/test/selenium-core/scripts/xmlextras.js +0 -153
  361. data/test/selenium-core/selenium-logo.png +0 -0
  362. data/test/selenium-core/selenium-test.css +0 -43
  363. data/test/selenium-core/selenium.css +0 -299
  364. data/test/selenium-core/xpath/dom.js +0 -428
  365. data/test/selenium-core/xpath/misc.js +0 -252
  366. data/test/selenium-core/xpath/xpath.js +0 -2223
  367. data/test/selenium/_login_as_cmsadmin.rsel +0 -4
  368. data/test/selenium/dashboard.rsel +0 -5
  369. data/test/selenium/html_blocks.rsel +0 -4
  370. data/test/selenium/login/failed_login.rsel +0 -8
  371. data/test/selenium/login/successful_login.rsel +0 -9
  372. data/test/selenium/page_templates.rsel +0 -12
  373. data/test/selenium/pages/edit_properties.rsel +0 -5
  374. data/test/selenium/site/view_home_page.rsel +0 -4
  375. data/test/selenium/sitemap/move_page.rsel +0 -9
  376. data/test/selenium/sitemap/open_section.rsel +0 -6
  377. data/test/selenium/sitemap/select_page.rsel +0 -12
  378. data/test/selenium/sitemap/select_section.rsel +0 -17
  379. data/test/test_helper.rb +0 -193
  380. data/test/test_logging.rb +0 -67
  381. data/test/unit/behaviors/attaching_test.rb +0 -357
  382. data/test/unit/behaviors/connectable_test.rb +0 -29
  383. data/test/unit/behaviors/dynamic_attributes_test.rb +0 -38
  384. data/test/unit/behaviors/publishable_test.rb +0 -84
  385. data/test/unit/behaviors/searching_test.rb +0 -102
  386. data/test/unit/behaviors/taggable_test.rb +0 -109
  387. data/test/unit/behaviors/versioning_test.rb +0 -36
  388. data/test/unit/extensions/active_record/base_test.rb +0 -10
  389. data/test/unit/extensions/hash_test.rb +0 -17
  390. data/test/unit/extensions/integer_test.rb +0 -10
  391. data/test/unit/helpers/application_helper_test.rb +0 -77
  392. data/test/unit/helpers/form_builder_test.rb +0 -36
  393. data/test/unit/helpers/menu_helper_test.rb +0 -242
  394. data/test/unit/helpers/page_helper_test.rb +0 -67
  395. data/test/unit/helpers/path_helper_test.rb +0 -57
  396. data/test/unit/lib/acts_as_content_page_test.rb +0 -72
  397. data/test/unit/lib/cms/authentication/controller_test.rb +0 -20
  398. data/test/unit/lib/cms/sitemap_test.rb +0 -206
  399. data/test/unit/lib/cms_domain_support_test.rb +0 -43
  400. data/test/unit/lib/command_line_test.rb +0 -70
  401. data/test/unit/lib/content_block_test.rb +0 -203
  402. data/test/unit/lib/content_rendering_support_test.rb +0 -40
  403. data/test/unit/lib/generators_test.rb +0 -40
  404. data/test/unit/lib/routes_test.rb +0 -57
  405. data/test/unit/models/attachment_test.rb +0 -116
  406. data/test/unit/models/category_test.rb +0 -40
  407. data/test/unit/models/category_type_test.rb +0 -8
  408. data/test/unit/models/connector_test.rb +0 -152
  409. data/test/unit/models/content_type_test.rb +0 -56
  410. data/test/unit/models/email_page_portlet_test.rb +0 -14
  411. data/test/unit/models/file_block_test.rb +0 -230
  412. data/test/unit/models/group_test.rb +0 -13
  413. data/test/unit/models/html_block_test.rb +0 -102
  414. data/test/unit/models/link_test.rb +0 -52
  415. data/test/unit/models/page_partial_test.rb +0 -29
  416. data/test/unit/models/page_route_test.rb +0 -29
  417. data/test/unit/models/page_template_test.rb +0 -40
  418. data/test/unit/models/page_test.rb +0 -792
  419. data/test/unit/models/permission_test.rb +0 -10
  420. data/test/unit/models/portlet_test.rb +0 -69
  421. data/test/unit/models/sections_test.rb +0 -264
  422. data/test/unit/models/site_test.rb +0 -50
  423. data/test/unit/models/task_test.rb +0 -141
  424. data/test/unit/models/user_test.rb +0 -352
  425. data/test/unit/schema_statements_test.rb +0 -41
@@ -1,63 +0,0 @@
1
- /*
2
-
3
- This is an experiment in creating a "selenese" parser that drastically
4
- cuts down on the line noise associated with writing tests in HTML.
5
-
6
- The 'parse' function will accept the follow sample commands.
7
-
8
- test-cases:
9
- //comment
10
- command "param"
11
- command "param" // comment
12
- command "param" "param2"
13
- command "param" "param2" // this is a comment
14
-
15
- TODO:
16
- 1) Deal with multiline parameters
17
- 2) Escape quotes properly
18
- 3) Determine whether this should/will become the "preferred" syntax
19
- for delivered Selenium self-test scripts
20
- */
21
-
22
-
23
- function separse(doc) {
24
- // Get object
25
- script = doc.getElementById('testcase')
26
- // Split into lines
27
- lines = script.text.split('\n');
28
-
29
-
30
- var command_pattern = / *(\w+) *"([^"]*)" *(?:"([^"]*)"){0,1}(?: *(\/\/ *.+))*/i;
31
- var comment_pattern = /^ *(\/\/ *.+)/
32
-
33
- // Regex each line into selenium command and convert into table row.
34
- // eg. "<command> <quote> <quote> <comment>"
35
- var new_test_source = '';
36
- var new_line = '';
37
- for (var x=0; x < lines.length; x++) {
38
- result = lines[x].match(command_pattern);
39
- if (result != null) {
40
- new_line = "<tr><td>" + (result[1] || '&nbsp;') + "</td>" +
41
- "<td>" + (result[2] || '&nbsp;') + "</td>" +
42
- "<td>" + (result[3] || '&nbsp;') + "</td>" +
43
- "<td>" + (result[4] || '&nbsp;') + "</td></tr>\n";
44
- new_test_source += new_line;
45
- }
46
- result = lines[x].match(comment_pattern);
47
- if (result != null) {
48
- new_line = '<tr><td rowspan="1" colspan="4">' +
49
- (result[1] || '&nbsp;') +
50
- '</td></tr>';
51
- new_test_source += new_line;
52
- }
53
- }
54
-
55
- // Create HTML Table
56
- body = doc.body
57
- body.innerHTML += "<table class='selenium' id='testtable'>"+
58
- new_test_source +
59
- "</table>";
60
-
61
- }
62
-
63
-
@@ -1,2409 +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
- * </ul>
102
- *
103
- * <p>
104
- * Without an explicit locator prefix, Selenium uses the following default
105
- * strategies:
106
- * </p>
107
- *
108
- * <ul class="simple">
109
- * <li><strong>dom</strong>, for locators starting with &quot;document.&quot;</li>
110
- * <li><strong>xpath</strong>, for locators starting with &quot;//&quot;</li>
111
- * <li><strong>identifier</strong>, otherwise</li>
112
- * </ul>
113
- *
114
- * <h3><a name="element-filters">Element Filters</a></h3>
115
- * <blockquote>
116
- * <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>
117
- * <p>Filters look much like locators, ie.</p>
118
- * <blockquote>
119
- * <em>filterType</em><strong>=</strong><em>argument</em></blockquote>
120
- *
121
- * <p>Supported element-filters are:</p>
122
- * <p><strong>value=</strong><em>valuePattern</em></p>
123
- * <blockquote>
124
- * Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.</blockquote>
125
- * <p><strong>index=</strong><em>index</em></p>
126
- * <blockquote>
127
- * Selects a single element based on its position in the list (offset from zero).</blockquote>
128
- * </blockquote>
129
- *
130
- * <h3><a name="patterns"></a>String-match Patterns</h3>
131
- *
132
- * <p>
133
- * Various Pattern syntaxes are available for matching string values:
134
- * </p>
135
- * <ul>
136
- * <li><strong>glob:</strong><em>pattern</em>:
137
- * Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a
138
- * kind of limited regular-expression syntax typically used in command-line
139
- * shells. In a glob pattern, "*" represents any sequence of characters, and "?"
140
- * represents any single character. Glob patterns match against the entire
141
- * string.</li>
142
- * <li><strong>regexp:</strong><em>regexp</em>:
143
- * Match a string using a regular-expression. The full power of JavaScript
144
- * regular-expressions is available.</li>
145
- * <li><strong>exact:</strong><em>string</em>:
146
- *
147
- * Match a string exactly, verbatim, without any of that fancy wildcard
148
- * stuff.</li>
149
- * </ul>
150
- * <p>
151
- * If no pattern prefix is specified, Selenium assumes that it's a "glob"
152
- * pattern.
153
- * </p>
154
- */
155
- this.browserbot = browserbot;
156
- this.optionLocatorFactory = new OptionLocatorFactory();
157
- // DGF for backwards compatibility
158
- this.page = function() {
159
- return browserbot;
160
- };
161
- this.defaultTimeout = Selenium.DEFAULT_TIMEOUT;
162
- this.mouseSpeed = 10;
163
- }
164
-
165
- Selenium.DEFAULT_TIMEOUT = 30 * 1000;
166
- Selenium.DEFAULT_MOUSE_SPEED = 10;
167
-
168
- Selenium.decorateFunctionWithTimeout = function(f, timeout) {
169
- if (f == null) {
170
- return null;
171
- }
172
- var timeoutValue = parseInt(timeout);
173
- if (isNaN(timeoutValue)) {
174
- throw new SeleniumError("Timeout is not a number: '" + timeout + "'");
175
- }
176
- var now = new Date().getTime();
177
- var timeoutTime = now + timeoutValue;
178
- return function() {
179
- if (new Date().getTime() > timeoutTime) {
180
- throw new SeleniumError("Timed out after " + timeoutValue + "ms");
181
- }
182
- return f();
183
- };
184
- }
185
-
186
- Selenium.createForWindow = function(window, proxyInjectionMode) {
187
- if (!window.location) {
188
- throw "error: not a window!";
189
- }
190
- return new Selenium(BrowserBot.createForWindow(window, proxyInjectionMode));
191
- };
192
-
193
- Selenium.prototype.reset = function() {
194
- this.defaultTimeout = Selenium.DEFAULT_TIMEOUT;
195
- // todo: this.browserbot.reset()
196
- this.browserbot.selectWindow("null");
197
- this.browserbot.resetPopups();
198
- };
199
-
200
- Selenium.prototype.doClick = function(locator) {
201
- /**
202
- * Clicks on a link, button, checkbox or radio button. If the click action
203
- * causes a new page to load (like a link usually does), call
204
- * waitForPageToLoad.
205
- *
206
- * @param locator an element locator
207
- *
208
- */
209
- var element = this.browserbot.findElement(locator);
210
- this.browserbot.clickElement(element);
211
- };
212
-
213
- Selenium.prototype.doDoubleClick = function(locator) {
214
- /**
215
- * Double clicks on a link, button, checkbox or radio button. If the double click action
216
- * causes a new page to load (like a link usually does), call
217
- * waitForPageToLoad.
218
- *
219
- * @param locator an element locator
220
- *
221
- */
222
- var element = this.browserbot.findElement(locator);
223
- this.browserbot.doubleClickElement(element);
224
- };
225
-
226
- Selenium.prototype.doClickAt = function(locator, coordString) {
227
- /**
228
- * Clicks on a link, button, checkbox or radio button. If the click action
229
- * causes a new page to load (like a link usually does), call
230
- * waitForPageToLoad.
231
- *
232
- * @param locator an element locator
233
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
234
- * event relative to the element returned by the locator.
235
- *
236
- */
237
- var element = this.browserbot.findElement(locator);
238
- var clientXY = getClientXY(element, coordString)
239
- this.browserbot.clickElement(element, clientXY[0], clientXY[1]);
240
- };
241
-
242
- Selenium.prototype.doDoubleClickAt = function(locator, coordString) {
243
- /**
244
- * Doubleclicks on a link, button, checkbox or radio button. If the action
245
- * causes a new page to load (like a link usually does), call
246
- * waitForPageToLoad.
247
- *
248
- * @param locator an element locator
249
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
250
- * event relative to the element returned by the locator.
251
- *
252
- */
253
- var element = this.browserbot.findElement(locator);
254
- var clientXY = getClientXY(element, coordString)
255
- this.browserbot.doubleClickElement(element, clientXY[0], clientXY[1]);
256
- };
257
-
258
- Selenium.prototype.doFireEvent = function(locator, eventName) {
259
- /**
260
- * Explicitly simulate an event, to trigger the corresponding &quot;on<em>event</em>&quot;
261
- * handler.
262
- *
263
- * @param locator an <a href="#locators">element locator</a>
264
- * @param eventName the event name, e.g. "focus" or "blur"
265
- */
266
- var element = this.browserbot.findElement(locator);
267
- triggerEvent(element, eventName, false);
268
- };
269
-
270
- Selenium.prototype.doKeyPress = function(locator, keySequence) {
271
- /**
272
- * Simulates a user pressing and releasing a key.
273
- *
274
- * @param locator an <a href="#locators">element locator</a>
275
- * @param keySequence Either be a string("\" followed by the numeric keycode
276
- * of the key to be pressed, normally the ASCII value of that key), or a single
277
- * character. For example: "w", "\119".
278
- */
279
- var element = this.browserbot.findElement(locator);
280
- triggerKeyEvent(element, 'keypress', keySequence, true,
281
- this.browserbot.controlKeyDown,
282
- this.browserbot.altKeyDown,
283
- this.browserbot.shiftKeyDown,
284
- this.browserbot.metaKeyDown);
285
- };
286
-
287
- Selenium.prototype.doShiftKeyDown = function() {
288
- /**
289
- * Press the shift key and hold it down until doShiftUp() is called or a new page is loaded.
290
- *
291
- */
292
- this.browserbot.shiftKeyDown = true;
293
- };
294
-
295
- Selenium.prototype.doShiftKeyUp = function() {
296
- /**
297
- * Release the shift key.
298
- *
299
- */
300
- this.browserbot.shiftKeyDown = false;
301
- };
302
-
303
- Selenium.prototype.doMetaKeyDown = function() {
304
- /**
305
- * Press the meta key and hold it down until doMetaUp() is called or a new page is loaded.
306
- *
307
- */
308
- this.browserbot.metaKeyDown = true;
309
- };
310
-
311
- Selenium.prototype.doMetaKeyUp = function() {
312
- /**
313
- * Release the meta key.
314
- *
315
- */
316
- this.browserbot.metaKeyDown = false;
317
- };
318
-
319
- Selenium.prototype.doAltKeyDown = function() {
320
- /**
321
- * Press the alt key and hold it down until doAltUp() is called or a new page is loaded.
322
- *
323
- */
324
- this.browserbot.altKeyDown = true;
325
- };
326
-
327
- Selenium.prototype.doAltKeyUp = function() {
328
- /**
329
- * Release the alt key.
330
- *
331
- */
332
- this.browserbot.altKeyDown = false;
333
- };
334
-
335
- Selenium.prototype.doControlKeyDown = function() {
336
- /**
337
- * Press the control key and hold it down until doControlUp() is called or a new page is loaded.
338
- *
339
- */
340
- this.browserbot.controlKeyDown = true;
341
- };
342
-
343
- Selenium.prototype.doControlKeyUp = function() {
344
- /**
345
- * Release the control key.
346
- *
347
- */
348
- this.browserbot.controlKeyDown = false;
349
- };
350
-
351
- Selenium.prototype.doKeyDown = function(locator, keySequence) {
352
- /**
353
- * Simulates a user pressing a key (without releasing it yet).
354
- *
355
- * @param locator an <a href="#locators">element locator</a>
356
- * @param keySequence Either be a string("\" followed by the numeric keycode
357
- * of the key to be pressed, normally the ASCII value of that key), or a single
358
- * character. For example: "w", "\119".
359
- */
360
- var element = this.browserbot.findElement(locator);
361
- triggerKeyEvent(element, 'keydown', keySequence, true,
362
- this.browserbot.controlKeyDown,
363
- this.browserbot.altKeyDown,
364
- this.browserbot.shiftKeyDown,
365
- this.browserbot.metaKeyDown);
366
- };
367
-
368
- Selenium.prototype.doKeyUp = function(locator, keySequence) {
369
- /**
370
- * Simulates a user releasing a key.
371
- *
372
- * @param locator an <a href="#locators">element locator</a>
373
- * @param keySequence Either be a string("\" followed by the numeric keycode
374
- * of the key to be pressed, normally the ASCII value of that key), or a single
375
- * character. For example: "w", "\119".
376
- */
377
- var element = this.browserbot.findElement(locator);
378
- triggerKeyEvent(element, 'keyup', keySequence, true,
379
- this.browserbot.controlKeyDown,
380
- this.browserbot.altKeyDown,
381
- this.browserbot.shiftKeyDown,
382
- this.browserbot.metaKeyDown);
383
- };
384
-
385
- function getClientXY(element, coordString) {
386
- // Parse coordString
387
- var coords = null;
388
- var x;
389
- var y;
390
- if (coordString) {
391
- coords = coordString.split(/,/);
392
- x = Number(coords[0]);
393
- y = Number(coords[1]);
394
- }
395
- else {
396
- x = y = 0;
397
- }
398
-
399
- // Get position of element,
400
- // Return 2 item array with clientX and clientY
401
- return [Selenium.prototype.getElementPositionLeft(element) + x, Selenium.prototype.getElementPositionTop(element) + y];
402
- }
403
-
404
- Selenium.prototype.doMouseOver = function(locator) {
405
- /**
406
- * Simulates a user hovering a mouse over the specified element.
407
- *
408
- * @param locator an <a href="#locators">element locator</a>
409
- */
410
- var element = this.browserbot.findElement(locator);
411
- this.browserbot.triggerMouseEvent(element, 'mouseover', true);
412
- };
413
-
414
- Selenium.prototype.doMouseOut = function(locator) {
415
- /**
416
- * Simulates a user moving the mouse pointer away from the specified element.
417
- *
418
- * @param locator an <a href="#locators">element locator</a>
419
- */
420
- var element = this.browserbot.findElement(locator);
421
- this.browserbot.triggerMouseEvent(element, 'mouseout', true);
422
- };
423
-
424
- Selenium.prototype.doMouseDown = function(locator) {
425
- /**
426
- * Simulates a user pressing the mouse button (without releasing it yet) on
427
- * the specified element.
428
- *
429
- * @param locator an <a href="#locators">element locator</a>
430
- */
431
- var element = this.browserbot.findElement(locator);
432
- this.browserbot.triggerMouseEvent(element, 'mousedown', true);
433
- };
434
-
435
- Selenium.prototype.doMouseDownAt = function(locator, coordString) {
436
- /**
437
- * Simulates a user pressing the mouse button (without releasing it yet) at
438
- * the specified location.
439
- *
440
- * @param locator an <a href="#locators">element locator</a>
441
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
442
- * event relative to the element returned by the locator.
443
- */
444
- var element = this.browserbot.findElement(locator);
445
- var clientXY = getClientXY(element, coordString)
446
-
447
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientXY[0], clientXY[1]);
448
- };
449
-
450
- Selenium.prototype.doMouseUp = function(locator) {
451
- /**
452
- * Simulates the event that occurs when the user releases the mouse button (i.e., stops
453
- * holding the button down) on the specified element.
454
- *
455
- * @param locator an <a href="#locators">element locator</a>
456
- */
457
- var element = this.browserbot.findElement(locator);
458
- this.browserbot.triggerMouseEvent(element, 'mouseup', true);
459
- };
460
-
461
- Selenium.prototype.doMouseUpAt = function(locator, coordString) {
462
- /**
463
- * Simulates the event that occurs when the user releases the mouse button (i.e., stops
464
- * holding the button down) at the specified location.
465
- *
466
- * @param locator an <a href="#locators">element locator</a>
467
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
468
- * event relative to the element returned by the locator.
469
- */
470
- var element = this.browserbot.findElement(locator);
471
- var clientXY = getClientXY(element, coordString)
472
-
473
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientXY[0], clientXY[1]);
474
- };
475
-
476
- Selenium.prototype.doMouseMove = function(locator) {
477
- /**
478
- * Simulates a user pressing the mouse button (without releasing it yet) on
479
- * the specified element.
480
- *
481
- * @param locator an <a href="#locators">element locator</a>
482
- */
483
- var element = this.browserbot.findElement(locator);
484
- this.browserbot.triggerMouseEvent(element, 'mousemove', true);
485
- };
486
-
487
- Selenium.prototype.doMouseMoveAt = function(locator, coordString) {
488
- /**
489
- * Simulates a user pressing the mouse button (without releasing it yet) on
490
- * the specified element.
491
- *
492
- * @param locator an <a href="#locators">element locator</a>
493
- * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse
494
- * event relative to the element returned by the locator.
495
- */
496
-
497
- var element = this.browserbot.findElement(locator);
498
- var clientXY = getClientXY(element, coordString)
499
-
500
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientXY[0], clientXY[1]);
501
- };
502
-
503
- Selenium.prototype.doType = function(locator, value) {
504
- /**
505
- * Sets the value of an input field, as though you typed it in.
506
- *
507
- * <p>Can also be used to set the value of combo boxes, check boxes, etc. In these cases,
508
- * value should be the value of the option selected, not the visible text.</p>
509
- *
510
- * @param locator an <a href="#locators">element locator</a>
511
- * @param value the value to type
512
- */
513
- if (this.browserbot.controlKeyDown || this.browserbot.altKeyDown || this.browserbot.metaKeyDown) {
514
- throw new SeleniumError("type not supported immediately after call to controlKeyDown() or altKeyDown() or metaKeyDown()");
515
- }
516
- // TODO fail if it can't be typed into.
517
- var element = this.browserbot.findElement(locator);
518
- if (this.browserbot.shiftKeyDown) {
519
- value = new String(value).toUpperCase();
520
- }
521
- this.browserbot.replaceText(element, value);
522
- };
523
-
524
- Selenium.prototype.doTypeKeys = function(locator, value) {
525
- /**
526
- * Simulates keystroke events on the specified element, as though you typed the value key-by-key.
527
- *
528
- * <p>This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string;
529
- * this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.</p>
530
- *
531
- * <p>Unlike the simple "type" command, which forces the specified value into the page directly, this command
532
- * may or may not have any visible effect, even in cases where typing keys would normally have a visible effect.
533
- * For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in
534
- * the field.</p>
535
- * <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
536
- * send the keystroke events corresponding to what you just typed.</p>
537
- *
538
- * @param locator an <a href="#locators">element locator</a>
539
- * @param value the value to type
540
- */
541
- var keys = new String(value).split("");
542
- for (var i = 0; i < keys.length; i++) {
543
- var c = keys[i];
544
- this.doKeyDown(locator, c);
545
- this.doKeyUp(locator, c);
546
- this.doKeyPress(locator, c);
547
- }
548
- };
549
-
550
- Selenium.prototype.doSetSpeed = function(value) {
551
- /**
552
- * 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.,
553
- * the delay is 0 milliseconds.
554
- *
555
- * @param value the number of milliseconds to pause after operation
556
- */
557
- throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire");
558
- };
559
-
560
- Selenium.prototype.doGetSpeed = function() {
561
- /**
562
- * 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.,
563
- * the delay is 0 milliseconds.
564
- *
565
- * See also setSpeed.
566
- */
567
- throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire");
568
- };
569
-
570
- Selenium.prototype.findToggleButton = function(locator) {
571
- var element = this.browserbot.findElement(locator);
572
- if (element.checked == null) {
573
- Assert.fail("Element " + locator + " is not a toggle-button.");
574
- }
575
- return element;
576
- }
577
-
578
- Selenium.prototype.doCheck = function(locator) {
579
- /**
580
- * Check a toggle-button (checkbox/radio)
581
- *
582
- * @param locator an <a href="#locators">element locator</a>
583
- */
584
- this.findToggleButton(locator).checked = true;
585
- };
586
-
587
- Selenium.prototype.doUncheck = function(locator) {
588
- /**
589
- * Uncheck a toggle-button (checkbox/radio)
590
- *
591
- * @param locator an <a href="#locators">element locator</a>
592
- */
593
- this.findToggleButton(locator).checked = false;
594
- };
595
-
596
- Selenium.prototype.doSelect = function(selectLocator, optionLocator) {
597
- /**
598
- * Select an option from a drop-down using an option locator.
599
- *
600
- * <p>
601
- * Option locators provide different ways of specifying options of an HTML
602
- * Select element (e.g. for selecting a specific option, or for asserting
603
- * that the selected option satisfies a specification). There are several
604
- * forms of Select Option Locator.
605
- * </p>
606
- * <ul>
607
- * <li><strong>label</strong>=<em>labelPattern</em>:
608
- * matches options based on their labels, i.e. the visible text. (This
609
- * is the default.)
610
- * <ul class="first last simple">
611
- * <li>label=regexp:^[Oo]ther</li>
612
- * </ul>
613
- * </li>
614
- * <li><strong>value</strong>=<em>valuePattern</em>:
615
- * matches options based on their values.
616
- * <ul class="first last simple">
617
- * <li>value=other</li>
618
- * </ul>
619
- *
620
- *
621
- * </li>
622
- * <li><strong>id</strong>=<em>id</em>:
623
- *
624
- * matches options based on their ids.
625
- * <ul class="first last simple">
626
- * <li>id=option1</li>
627
- * </ul>
628
- * </li>
629
- * <li><strong>index</strong>=<em>index</em>:
630
- * matches an option based on its index (offset from zero).
631
- * <ul class="first last simple">
632
- *
633
- * <li>index=2</li>
634
- * </ul>
635
- * </li>
636
- * </ul>
637
- * <p>
638
- * If no option locator prefix is provided, the default behaviour is to match on <strong>label</strong>.
639
- * </p>
640
- *
641
- *
642
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
643
- * @param optionLocator an option locator (a label by default)
644
- */
645
- var element = this.browserbot.findElement(selectLocator);
646
- if (!("options" in element)) {
647
- throw new SeleniumError("Specified element is not a Select (has no options)");
648
- }
649
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
650
- var option = locator.findOption(element);
651
- this.browserbot.selectOption(element, option);
652
- };
653
-
654
-
655
-
656
- Selenium.prototype.doAddSelection = function(locator, optionLocator) {
657
- /**
658
- * Add a selection to the set of selected options in a multi-select element using an option locator.
659
- *
660
- * @see #doSelect for details of option locators
661
- *
662
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
663
- * @param optionLocator an option locator (a label by default)
664
- */
665
- var element = this.browserbot.findElement(locator);
666
- if (!("options" in element)) {
667
- throw new SeleniumError("Specified element is not a Select (has no options)");
668
- }
669
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
670
- var option = locator.findOption(element);
671
- this.browserbot.addSelection(element, option);
672
- };
673
-
674
- Selenium.prototype.doRemoveSelection = function(locator, optionLocator) {
675
- /**
676
- * Remove a selection from the set of selected options in a multi-select element using an option locator.
677
- *
678
- * @see #doSelect for details of option locators
679
- *
680
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
681
- * @param optionLocator an option locator (a label by default)
682
- */
683
-
684
- var element = this.browserbot.findElement(locator);
685
- if (!("options" in element)) {
686
- throw new SeleniumError("Specified element is not a Select (has no options)");
687
- }
688
- var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
689
- var option = locator.findOption(element);
690
- this.browserbot.removeSelection(element, option);
691
- };
692
-
693
- Selenium.prototype.doRemoveAllSelections = function(locator) {
694
- /**
695
- * Unselects all of the selected options in a multi-select element.
696
- *
697
- * @param locator an <a href="#locators">element locator</a> identifying a multi-select box
698
- */
699
- var element = this.browserbot.findElement(locator);
700
- if (!("options" in element)) {
701
- throw new SeleniumError("Specified element is not a Select (has no options)");
702
- }
703
- for (var i = 0; i < element.options.length; i++) {
704
- this.browserbot.removeSelection(element, element.options[i]);
705
- }
706
- }
707
-
708
- Selenium.prototype.doSubmit = function(formLocator) {
709
- /**
710
- * Submit the specified form. This is particularly useful for forms without
711
- * submit buttons, e.g. single-input "Search" forms.
712
- *
713
- * @param formLocator an <a href="#locators">element locator</a> for the form you want to submit
714
- */
715
- var form = this.browserbot.findElement(formLocator);
716
- return this.browserbot.submit(form);
717
-
718
- };
719
-
720
- Selenium.prototype.makePageLoadCondition = function(timeout) {
721
- if (timeout == null) {
722
- timeout = this.defaultTimeout;
723
- }
724
- return Selenium.decorateFunctionWithTimeout(fnBind(this._isNewPageLoaded, this), timeout);
725
- };
726
-
727
- Selenium.prototype.doOpen = function(url) {
728
- /**
729
- * Opens an URL in the test frame. This accepts both relative and absolute
730
- * URLs.
731
- *
732
- * The &quot;open&quot; command waits for the page to load before proceeding,
733
- * ie. the &quot;AndWait&quot; suffix is implicit.
734
- *
735
- * <em>Note</em>: The URL must be on the same domain as the runner HTML
736
- * due to security restrictions in the browser (Same Origin Policy). If you
737
- * need to open an URL on another domain, use the Selenium Server to start a
738
- * new browser session on that domain.
739
- *
740
- * @param url the URL to open; may be relative or absolute
741
- */
742
- this.browserbot.openLocation(url);
743
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
744
- return this.makePageLoadCondition();
745
- } // in PI mode, just return "OK"; the server will waitForLoad
746
- };
747
-
748
- Selenium.prototype.doOpenWindow = function(url, windowID) {
749
- /**
750
- * Opens a popup window (if a window with that ID isn't already open).
751
- * After opening the window, you'll need to select it using the selectWindow
752
- * command.
753
- *
754
- * <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).
755
- * In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using
756
- * an empty (blank) url, like this: openWindow("", "myFunnyWindow").</p>
757
- *
758
- * @param url the URL to open, which can be blank
759
- * @param windowID the JavaScript window ID of the window to select
760
- */
761
- this.browserbot.openWindow(url, windowID);
762
- };
763
-
764
- Selenium.prototype.doSelectWindow = function(windowID) {
765
- /**
766
- * Selects a popup window; once a popup window has been selected, all
767
- * commands go to that window. To select the main window again, use null
768
- * as the target.
769
- *
770
- * <p>Note that there is a big difference between a window's internal JavaScript "name" property
771
- * and the "title" of a given window's document (which is normally what you actually see, as an end user,
772
- * in the title bar of the window). The "name" is normally invisible to the end-user; it's the second
773
- * parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag)
774
- * (which selenium intercepts).</p>
775
- *
776
- * <p>Selenium has several strategies for finding the window object referred to by the "windowID" parameter.</p>
777
- *
778
- * <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>
779
- * <p>2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed
780
- * that this variable contains the return value from a call to the JavaScript window.open() method.</p>
781
- * <p>3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".</p>
782
- * <p>4.) If <i>that</i> fails, we'll try looping over all of the known windows to try to find the appropriate "title".
783
- * Since "title" is not necessarily unique, this may have unexpected behavior.</p>
784
- *
785
- * <p>If you're having trouble figuring out what is the name of a window that you want to manipulate, look at the selenium log messages
786
- * which identify the names of windows created via window.open (and therefore intercepted by selenium). You will see messages
787
- * like the following for each window as it is opened:</p>
788
- *
789
- * <p><code>debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"</code></p>
790
- *
791
- * <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).
792
- * (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
793
- * an empty (blank) url, like this: openWindow("", "myFunnyWindow").</p>
794
- *
795
- * @param windowID the JavaScript window ID of the window to select
796
- */
797
- this.browserbot.selectWindow(windowID);
798
- };
799
-
800
- Selenium.prototype.doSelectFrame = function(locator) {
801
- /**
802
- * Selects a frame within the current window. (You may invoke this command
803
- * multiple times to select nested frames.) To select the parent frame, use
804
- * "relative=parent" as a locator; to select the top frame, use "relative=top".
805
- * You can also select a frame by its 0-based index number; select the first frame with
806
- * "index=0", or the third frame with "index=2".
807
- *
808
- * <p>You may also use a DOM expression to identify the frame you want directly,
809
- * like this: <code>dom=frames["main"].frames["subframe"]</code></p>
810
- *
811
- * @param locator an <a href="#locators">element locator</a> identifying a frame or iframe
812
- */
813
- this.browserbot.selectFrame(locator);
814
- };
815
-
816
- Selenium.prototype.getWhetherThisFrameMatchFrameExpression = function(currentFrameString, target) {
817
- /**
818
- * Determine whether current/locator identify the frame containing this running code.
819
- *
820
- * <p>This is useful in proxy injection mode, where this code runs in every
821
- * browser frame and window, and sometimes the selenium server needs to identify
822
- * the "current" frame. In this case, when the test calls selectFrame, this
823
- * routine is called for each frame to figure out which one has been selected.
824
- * The selected frame will return true, while all others will return false.</p>
825
- *
826
- * @param currentFrameString starting frame
827
- * @param target new frame (which might be relative to the current one)
828
- * @return boolean true if the new frame is this code's window
829
- */
830
- return this.browserbot.doesThisFrameMatchFrameExpression(currentFrameString, target);
831
- };
832
-
833
- Selenium.prototype.getWhetherThisWindowMatchWindowExpression = function(currentWindowString, target) {
834
- /**
835
- * Determine whether currentWindowString plus target identify the window containing this running code.
836
- *
837
- * <p>This is useful in proxy injection mode, where this code runs in every
838
- * browser frame and window, and sometimes the selenium server needs to identify
839
- * the "current" window. In this case, when the test calls selectWindow, this
840
- * routine is called for each window to figure out which one has been selected.
841
- * The selected window will return true, while all others will return false.</p>
842
- *
843
- * @param currentWindowString starting window
844
- * @param target new window (which might be relative to the current one, e.g., "_parent")
845
- * @return boolean true if the new window is this code's window
846
- */
847
- if (window.opener!=null && window.opener[target]!=null && window.opener[target]==window) {
848
- return true;
849
- }
850
- return false;
851
- };
852
-
853
- Selenium.prototype.doWaitForPopUp = function(windowID, timeout) {
854
- /**
855
- * Waits for a popup window to appear and load up.
856
- *
857
- * @param windowID the JavaScript window ID of the window that will appear
858
- * @param timeout a timeout in milliseconds, after which the action will return with an error
859
- */
860
- var popupLoadedPredicate = function () {
861
- var targetWindow = selenium.browserbot.getWindowByName(windowID, true);
862
- if (!targetWindow) return false;
863
- if (!targetWindow.location) return false;
864
- if ("about:blank" == targetWindow.location) return false;
865
- if (browserVersion.isKonqueror) {
866
- if ("/" == targetWindow.location.href) {
867
- // apparently Konqueror uses this as the temporary location, instead of about:blank
868
- return false;
869
- }
870
- }
871
- if (browserVersion.isSafari) {
872
- if(targetWindow.location.href == selenium.browserbot.buttonWindow.location.href) {
873
- // Apparently Safari uses this as the temporary location, instead of about:blank
874
- // what a world!
875
- LOG.debug("DGF what a world!");
876
- return false;
877
- }
878
- }
879
- if (!targetWindow.document) return false;
880
- if (!selenium.browserbot.getCurrentWindow().document.readyState) {
881
- // This is Firefox, with no readyState extension
882
- return true;
883
- }
884
- if ('complete' != targetWindow.document.readyState) return false;
885
- return true;
886
- };
887
-
888
- return Selenium.decorateFunctionWithTimeout(popupLoadedPredicate, timeout);
889
- }
890
-
891
- Selenium.prototype.doWaitForPopUp.dontCheckAlertsAndConfirms = true;
892
-
893
- Selenium.prototype.doChooseCancelOnNextConfirmation = function() {
894
- /**
895
- * By default, Selenium's overridden window.confirm() function will
896
- * return true, as if the user had manually clicked OK; after running
897
- * this command, the next call to confirm() will return false, as if
898
- * the user had clicked Cancel. Selenium will then resume using the
899
- * default behavior for future confirmations, automatically returning
900
- * true (OK) unless/until you explicitly call this command for each
901
- * confirmation.
902
- *
903
- */
904
- this.browserbot.cancelNextConfirmation(false);
905
- };
906
-
907
- Selenium.prototype.doChooseOkOnNextConfirmation = function() {
908
- /**
909
- * Undo the effect of calling chooseCancelOnNextConfirmation. Note
910
- * that Selenium's overridden window.confirm() function will normally automatically
911
- * return true, as if the user had manually clicked OK, so you shouldn't
912
- * need to use this command unless for some reason you need to change
913
- * your mind prior to the next confirmation. After any confirmation, Selenium will resume using the
914
- * default behavior for future confirmations, automatically returning
915
- * true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each
916
- * confirmation.
917
- *
918
- */
919
- this.browserbot.cancelNextConfirmation(true);
920
- };
921
-
922
- Selenium.prototype.doAnswerOnNextPrompt = function(answer) {
923
- /**
924
- * Instructs Selenium to return the specified answer string in response to
925
- * the next JavaScript prompt [window.prompt()].
926
- *
927
- *
928
- * @param answer the answer to give in response to the prompt pop-up
929
- */
930
- this.browserbot.setNextPromptResult(answer);
931
- };
932
-
933
- Selenium.prototype.doGoBack = function() {
934
- /**
935
- * Simulates the user clicking the "back" button on their browser.
936
- *
937
- */
938
- this.browserbot.goBack();
939
- };
940
-
941
- Selenium.prototype.doRefresh = function() {
942
- /**
943
- * Simulates the user clicking the "Refresh" button on their browser.
944
- *
945
- */
946
- this.browserbot.refresh();
947
- };
948
-
949
- Selenium.prototype.doClose = function() {
950
- /**
951
- * Simulates the user clicking the "close" button in the titlebar of a popup
952
- * window or tab.
953
- */
954
- this.browserbot.close();
955
- };
956
-
957
- Selenium.prototype.ensureNoUnhandledPopups = function() {
958
- if (this.browserbot.hasAlerts()) {
959
- throw new SeleniumError("There was an unexpected Alert! [" + this.browserbot.getNextAlert() + "]");
960
- }
961
- if ( this.browserbot.hasConfirmations() ) {
962
- throw new SeleniumError("There was an unexpected Confirmation! [" + this.browserbot.getNextConfirmation() + "]");
963
- }
964
- };
965
-
966
- Selenium.prototype.isAlertPresent = function() {
967
- /**
968
- * Has an alert occurred?
969
- *
970
- * <p>
971
- * This function never throws an exception
972
- * </p>
973
- * @return boolean true if there is an alert
974
- */
975
- return this.browserbot.hasAlerts();
976
- };
977
-
978
- Selenium.prototype.isPromptPresent = function() {
979
- /**
980
- * Has a prompt occurred?
981
- *
982
- * <p>
983
- * This function never throws an exception
984
- * </p>
985
- * @return boolean true if there is a pending prompt
986
- */
987
- return this.browserbot.hasPrompts();
988
- };
989
-
990
- Selenium.prototype.isConfirmationPresent = function() {
991
- /**
992
- * Has confirm() been called?
993
- *
994
- * <p>
995
- * This function never throws an exception
996
- * </p>
997
- * @return boolean true if there is a pending confirmation
998
- */
999
- return this.browserbot.hasConfirmations();
1000
- };
1001
- Selenium.prototype.getAlert = function() {
1002
- /**
1003
- * Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts.
1004
- *
1005
- * <p>Getting an alert has the same effect as manually clicking OK. If an
1006
- * alert is generated but you do not get/verify it, the next Selenium action
1007
- * will fail.</p>
1008
- *
1009
- * <p>NOTE: under Selenium, JavaScript alerts will NOT pop up a visible alert
1010
- * dialog.</p>
1011
- *
1012
- * <p>NOTE: Selenium does NOT support JavaScript alerts that are generated in a
1013
- * page's onload() event handler. In this case a visible dialog WILL be
1014
- * generated and Selenium will hang until someone manually clicks OK.</p>
1015
- * @return string The message of the most recent JavaScript alert
1016
- */
1017
- if (!this.browserbot.hasAlerts()) {
1018
- Assert.fail("There were no alerts");
1019
- }
1020
- return this.browserbot.getNextAlert();
1021
- };
1022
- Selenium.prototype.getAlert.dontCheckAlertsAndConfirms = true;
1023
-
1024
- Selenium.prototype.getConfirmation = function() {
1025
- /**
1026
- * Retrieves the message of a JavaScript confirmation dialog generated during
1027
- * the previous action.
1028
- *
1029
- * <p>
1030
- * By default, the confirm function will return true, having the same effect
1031
- * as manually clicking OK. This can be changed by prior execution of the
1032
- * chooseCancelOnNextConfirmation command. If an confirmation is generated
1033
- * but you do not get/verify it, the next Selenium action will fail.
1034
- * </p>
1035
- *
1036
- * <p>
1037
- * NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible
1038
- * dialog.
1039
- * </p>
1040
- *
1041
- * <p>
1042
- * NOTE: Selenium does NOT support JavaScript confirmations that are
1043
- * generated in a page's onload() event handler. In this case a visible
1044
- * dialog WILL be generated and Selenium will hang until you manually click
1045
- * OK.
1046
- * </p>
1047
- *
1048
- * @return string the message of the most recent JavaScript confirmation dialog
1049
- */
1050
- if (!this.browserbot.hasConfirmations()) {
1051
- Assert.fail("There were no confirmations");
1052
- }
1053
- return this.browserbot.getNextConfirmation();
1054
- };
1055
- Selenium.prototype.getConfirmation.dontCheckAlertsAndConfirms = true;
1056
-
1057
- Selenium.prototype.getPrompt = function() {
1058
- /**
1059
- * Retrieves the message of a JavaScript question prompt dialog generated during
1060
- * the previous action.
1061
- *
1062
- * <p>Successful handling of the prompt requires prior execution of the
1063
- * answerOnNextPrompt command. If a prompt is generated but you
1064
- * do not get/verify it, the next Selenium action will fail.</p>
1065
- *
1066
- * <p>NOTE: under Selenium, JavaScript prompts will NOT pop up a visible
1067
- * dialog.</p>
1068
- *
1069
- * <p>NOTE: Selenium does NOT support JavaScript prompts that are generated in a
1070
- * page's onload() event handler. In this case a visible dialog WILL be
1071
- * generated and Selenium will hang until someone manually clicks OK.</p>
1072
- * @return string the message of the most recent JavaScript question prompt
1073
- */
1074
- if (! this.browserbot.hasPrompts()) {
1075
- Assert.fail("There were no prompts");
1076
- }
1077
- return this.browserbot.getNextPrompt();
1078
- };
1079
-
1080
- Selenium.prototype.getLocation = function() {
1081
- /** Gets the absolute URL of the current page.
1082
- *
1083
- * @return string the absolute URL of the current page
1084
- */
1085
- return this.browserbot.getCurrentWindow().location;
1086
- };
1087
-
1088
- Selenium.prototype.getTitle = function() {
1089
- /** Gets the title of the current page.
1090
- *
1091
- * @return string the title of the current page
1092
- */
1093
- return this.browserbot.getTitle();
1094
- };
1095
-
1096
-
1097
- Selenium.prototype.getBodyText = function() {
1098
- /**
1099
- * Gets the entire text of the page.
1100
- * @return string the entire text of the page
1101
- */
1102
- return this.browserbot.bodyText();
1103
- };
1104
-
1105
-
1106
- Selenium.prototype.getValue = function(locator) {
1107
- /**
1108
- * Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter).
1109
- * For checkbox/radio elements, the value will be "on" or "off" depending on
1110
- * whether the element is checked or not.
1111
- *
1112
- * @param locator an <a href="#locators">element locator</a>
1113
- * @return string the element value, or "on/off" for checkbox/radio elements
1114
- */
1115
- var element = this.browserbot.findElement(locator)
1116
- return getInputValue(element).trim();
1117
- }
1118
-
1119
- Selenium.prototype.getText = function(locator) {
1120
- /**
1121
- * Gets the text of an element. This works for any element that contains
1122
- * text. This command uses either the textContent (Mozilla-like browsers) or
1123
- * the innerText (IE-like browsers) of the element, which is the rendered
1124
- * text shown to the user.
1125
- *
1126
- * @param locator an <a href="#locators">element locator</a>
1127
- * @return string the text of the element
1128
- */
1129
- var element = this.browserbot.findElement(locator);
1130
- return getText(element).trim();
1131
- };
1132
-
1133
- Selenium.prototype.doHighlight = function(locator) {
1134
- /**
1135
- * Briefly changes the backgroundColor of the specified element yellow. Useful for debugging.
1136
- *
1137
- * @param locator an <a href="#locators">element locator</a>
1138
- */
1139
- var element = this.browserbot.findElement(locator);
1140
- this.browserbot.highlight(element, true);
1141
- };
1142
-
1143
- Selenium.prototype.getEval = function(script) {
1144
- /** Gets the result of evaluating the specified JavaScript snippet. The snippet may
1145
- * have multiple lines, but only the result of the last line will be returned.
1146
- *
1147
- * <p>Note that, by default, the snippet will run in the context of the "selenium"
1148
- * object itself, so <code>this</code> will refer to the Selenium object. Use <code>window</code> to
1149
- * refer to the window of your application, e.g. <code>window.document.getElementById('foo')</code></p>
1150
- *
1151
- * <p>If you need to use
1152
- * a locator to refer to a single element in your application page, you can
1153
- * use <code>this.browserbot.findElement("id=foo")</code> where "id=foo" is your locator.</p>
1154
- *
1155
- * @param script the JavaScript snippet to run
1156
- * @return string the results of evaluating the snippet
1157
- */
1158
- try {
1159
- var window = this.browserbot.getCurrentWindow();
1160
- var result = eval(script);
1161
- // Selenium RC doesn't allow returning null
1162
- if (null == result) return "null";
1163
- return result;
1164
- } catch (e) {
1165
- throw new SeleniumError("Threw an exception: " + e.message);
1166
- }
1167
- };
1168
-
1169
- Selenium.prototype.isChecked = function(locator) {
1170
- /**
1171
- * Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button.
1172
- * @param locator an <a href="#locators">element locator</a> pointing to a checkbox or radio button
1173
- * @return boolean true if the checkbox is checked, false otherwise
1174
- */
1175
- var element = this.browserbot.findElement(locator);
1176
- if (element.checked == null) {
1177
- throw new SeleniumError("Element " + locator + " is not a toggle-button.");
1178
- }
1179
- return element.checked;
1180
- };
1181
-
1182
- Selenium.prototype.getTable = function(tableCellAddress) {
1183
- /**
1184
- * Gets the text from a cell of a table. The cellAddress syntax
1185
- * tableLocator.row.column, where row and column start at 0.
1186
- *
1187
- * @param tableCellAddress a cell address, e.g. "foo.1.4"
1188
- * @return string the text from the specified cell
1189
- */
1190
- // This regular expression matches "tableName.row.column"
1191
- // For example, "mytable.3.4"
1192
- pattern = /(.*)\.(\d+)\.(\d+)/;
1193
-
1194
- if(!pattern.test(tableCellAddress)) {
1195
- throw new SeleniumError("Invalid target format. Correct format is tableName.rowNum.columnNum");
1196
- }
1197
-
1198
- pieces = tableCellAddress.match(pattern);
1199
-
1200
- tableName = pieces[1];
1201
- row = pieces[2];
1202
- col = pieces[3];
1203
-
1204
- var table = this.browserbot.findElement(tableName);
1205
- if (row > table.rows.length) {
1206
- Assert.fail("Cannot access row " + row + " - table has " + table.rows.length + " rows");
1207
- }
1208
- else if (col > table.rows[row].cells.length) {
1209
- Assert.fail("Cannot access column " + col + " - table row has " + table.rows[row].cells.length + " columns");
1210
- }
1211
- else {
1212
- actualContent = getText(table.rows[row].cells[col]);
1213
- return actualContent.trim();
1214
- }
1215
- return null;
1216
- };
1217
-
1218
- Selenium.prototype.getSelectedLabels = function(selectLocator) {
1219
- /** Gets all option labels (visible text) for selected options in the specified select or multi-select element.
1220
- *
1221
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1222
- * @return string[] an array of all selected option labels in the specified select drop-down
1223
- */
1224
- return this.findSelectedOptionProperties(selectLocator, "text");
1225
- }
1226
-
1227
- Selenium.prototype.getSelectedLabel = function(selectLocator) {
1228
- /** Gets option label (visible text) for selected option in the specified select element.
1229
- *
1230
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1231
- * @return string the selected option label in the specified select drop-down
1232
- */
1233
- return this.findSelectedOptionProperty(selectLocator, "text");
1234
- }
1235
-
1236
- Selenium.prototype.getSelectedValues = function(selectLocator) {
1237
- /** Gets all option values (value attributes) for selected options in the specified select or multi-select element.
1238
- *
1239
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1240
- * @return string[] an array of all selected option values in the specified select drop-down
1241
- */
1242
- return this.findSelectedOptionProperties(selectLocator, "value");
1243
- }
1244
-
1245
- Selenium.prototype.getSelectedValue = function(selectLocator) {
1246
- /** Gets option value (value attribute) for selected option in the specified select element.
1247
- *
1248
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1249
- * @return string the selected option value in the specified select drop-down
1250
- */
1251
- return this.findSelectedOptionProperty(selectLocator, "value");
1252
- }
1253
-
1254
- Selenium.prototype.getSelectedIndexes = function(selectLocator) {
1255
- /** Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.
1256
- *
1257
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1258
- * @return string[] an array of all selected option indexes in the specified select drop-down
1259
- */
1260
- return this.findSelectedOptionProperties(selectLocator, "index");
1261
- }
1262
-
1263
- Selenium.prototype.getSelectedIndex = function(selectLocator) {
1264
- /** Gets option index (option number, starting at 0) for selected option in the specified select element.
1265
- *
1266
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1267
- * @return string the selected option index in the specified select drop-down
1268
- */
1269
- return this.findSelectedOptionProperty(selectLocator, "index");
1270
- }
1271
-
1272
- Selenium.prototype.getSelectedIds = function(selectLocator) {
1273
- /** Gets all option element IDs for selected options in the specified select or multi-select element.
1274
- *
1275
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1276
- * @return string[] an array of all selected option IDs in the specified select drop-down
1277
- */
1278
- return this.findSelectedOptionProperties(selectLocator, "id");
1279
- }
1280
-
1281
- Selenium.prototype.getSelectedId = function(selectLocator) {
1282
- /** Gets option element ID for selected option in the specified select element.
1283
- *
1284
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1285
- * @return string the selected option ID in the specified select drop-down
1286
- */
1287
- return this.findSelectedOptionProperty(selectLocator, "id");
1288
- }
1289
-
1290
- Selenium.prototype.isSomethingSelected = function(selectLocator) {
1291
- /** Determines whether some option in a drop-down menu is selected.
1292
- *
1293
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1294
- * @return boolean true if some option has been selected, false otherwise
1295
- */
1296
- var element = this.browserbot.findElement(selectLocator);
1297
- if (!("options" in element)) {
1298
- throw new SeleniumError("Specified element is not a Select (has no options)");
1299
- }
1300
-
1301
- var selectedOptions = [];
1302
-
1303
- for (var i = 0; i < element.options.length; i++) {
1304
- if (element.options[i].selected)
1305
- {
1306
- return true;
1307
- }
1308
- }
1309
- return false;
1310
- }
1311
-
1312
- Selenium.prototype.findSelectedOptionProperties = function(locator, property) {
1313
- var element = this.browserbot.findElement(locator);
1314
- if (!("options" in element)) {
1315
- throw new SeleniumError("Specified element is not a Select (has no options)");
1316
- }
1317
-
1318
- var selectedOptions = [];
1319
-
1320
- for (var i = 0; i < element.options.length; i++) {
1321
- if (element.options[i].selected)
1322
- {
1323
- var propVal = element.options[i][property];
1324
- selectedOptions.push(propVal);
1325
- }
1326
- }
1327
- if (selectedOptions.length == 0) Assert.fail("No option selected");
1328
- return selectedOptions;
1329
- }
1330
-
1331
- Selenium.prototype.findSelectedOptionProperty = function(locator, property) {
1332
- var selectedOptions = this.findSelectedOptionProperties(locator, property);
1333
- if (selectedOptions.length > 1) {
1334
- Assert.fail("More than one selected option!");
1335
- }
1336
- return selectedOptions[0];
1337
- }
1338
-
1339
- Selenium.prototype.getSelectOptions = function(selectLocator) {
1340
- /** Gets all option labels in the specified select drop-down.
1341
- *
1342
- * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1343
- * @return string[] an array of all option labels in the specified select drop-down
1344
- */
1345
- var element = this.browserbot.findElement(selectLocator);
1346
-
1347
- var selectOptions = [];
1348
-
1349
- for (var i = 0; i < element.options.length; i++) {
1350
- var option = element.options[i].text;
1351
- selectOptions.push(option);
1352
- }
1353
-
1354
- return selectOptions;
1355
- };
1356
-
1357
-
1358
- Selenium.prototype.getAttribute = function(attributeLocator) {
1359
- /**
1360
- * Gets the value of an element attribute.
1361
- *
1362
- * @param attributeLocator an element locator followed by an &#064; sign and then the name of the attribute, e.g. "foo&#064;bar"
1363
- * @return string the value of the specified attribute
1364
- */
1365
- var result = this.browserbot.findAttribute(attributeLocator);
1366
- if (result == null) {
1367
- throw new SeleniumError("Could not find element attribute: " + attributeLocator);
1368
- }
1369
- return result;
1370
- };
1371
-
1372
- Selenium.prototype.isTextPresent = function(pattern) {
1373
- /**
1374
- * Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.
1375
- * @param pattern a <a href="#patterns">pattern</a> to match with the text of the page
1376
- * @return boolean true if the pattern matches the text, false otherwise
1377
- */
1378
- var allText = this.browserbot.bodyText();
1379
-
1380
- var patternMatcher = new PatternMatcher(pattern);
1381
- if (patternMatcher.strategy == PatternMatcher.strategies.glob) {
1382
- if (pattern.indexOf("glob:")==0) {
1383
- pattern = pattern.substring("glob:".length); // strip off "glob:"
1384
- }
1385
- patternMatcher.matcher = new PatternMatcher.strategies.globContains(pattern);
1386
- }
1387
- else if (patternMatcher.strategy == PatternMatcher.strategies.exact) {
1388
- pattern = pattern.substring("exact:".length); // strip off "exact:"
1389
- return allText.indexOf(pattern) != -1;
1390
- }
1391
- return patternMatcher.matches(allText);
1392
- };
1393
-
1394
- Selenium.prototype.isElementPresent = function(locator) {
1395
- /**
1396
- * Verifies that the specified element is somewhere on the page.
1397
- * @param locator an <a href="#locators">element locator</a>
1398
- * @return boolean true if the element is present, false otherwise
1399
- */
1400
- var element = this.browserbot.findElementOrNull(locator);
1401
- if (element == null) {
1402
- return false;
1403
- }
1404
- return true;
1405
- };
1406
-
1407
- Selenium.prototype.isVisible = function(locator) {
1408
- /**
1409
- * Determines if the specified element is visible. An
1410
- * element can be rendered invisible by setting the CSS "visibility"
1411
- * property to "hidden", or the "display" property to "none", either for the
1412
- * element itself or one if its ancestors. This method will fail if
1413
- * the element is not present.
1414
- *
1415
- * @param locator an <a href="#locators">element locator</a>
1416
- * @return boolean true if the specified element is visible, false otherwise
1417
- */
1418
- var element;
1419
- element = this.browserbot.findElement(locator);
1420
- var visibility = this.findEffectiveStyleProperty(element, "visibility");
1421
- var _isDisplayed = this._isDisplayed(element);
1422
- return (visibility != "hidden" && _isDisplayed);
1423
- };
1424
-
1425
- Selenium.prototype.findEffectiveStyleProperty = function(element, property) {
1426
- var effectiveStyle = this.findEffectiveStyle(element);
1427
- var propertyValue = effectiveStyle[property];
1428
- if (propertyValue == 'inherit' && element.parentNode.style) {
1429
- return this.findEffectiveStyleProperty(element.parentNode, property);
1430
- }
1431
- return propertyValue;
1432
- };
1433
-
1434
- Selenium.prototype._isDisplayed = function(element) {
1435
- var display = this.findEffectiveStyleProperty(element, "display");
1436
- if (display == "none") return false;
1437
- if (element.parentNode.style) {
1438
- return this._isDisplayed(element.parentNode);
1439
- }
1440
- return true;
1441
- };
1442
-
1443
- Selenium.prototype.findEffectiveStyle = function(element) {
1444
- if (element.style == undefined) {
1445
- return undefined; // not a styled element
1446
- }
1447
- if (window.getComputedStyle) {
1448
- // DOM-Level-2-CSS
1449
- return this.browserbot.getCurrentWindow().getComputedStyle(element, null);
1450
- }
1451
- if (element.currentStyle) {
1452
- // non-standard IE alternative
1453
- return element.currentStyle;
1454
- // TODO: this won't really work in a general sense, as
1455
- // currentStyle is not identical to getComputedStyle()
1456
- // ... but it's good enough for "visibility"
1457
- }
1458
- throw new SeleniumError("cannot determine effective stylesheet in this browser");
1459
- };
1460
-
1461
- Selenium.prototype.isEditable = function(locator) {
1462
- /**
1463
- * Determines whether the specified input element is editable, ie hasn't been disabled.
1464
- * This method will fail if the specified element isn't an input element.
1465
- *
1466
- * @param locator an <a href="#locators">element locator</a>
1467
- * @return boolean true if the input element is editable, false otherwise
1468
- */
1469
- var element = this.browserbot.findElement(locator);
1470
- if (element.value == undefined) {
1471
- Assert.fail("Element " + locator + " is not an input.");
1472
- }
1473
- return !element.disabled;
1474
- };
1475
-
1476
- Selenium.prototype.getAllButtons = function() {
1477
- /** Returns the IDs of all buttons on the page.
1478
- *
1479
- * <p>If a given button has no ID, it will appear as "" in this array.</p>
1480
- *
1481
- * @return string[] the IDs of all buttons on the page
1482
- */
1483
- return this.browserbot.getAllButtons();
1484
- };
1485
-
1486
- Selenium.prototype.getAllLinks = function() {
1487
- /** Returns the IDs of all links on the page.
1488
- *
1489
- * <p>If a given link has no ID, it will appear as "" in this array.</p>
1490
- *
1491
- * @return string[] the IDs of all links on the page
1492
- */
1493
- return this.browserbot.getAllLinks();
1494
- };
1495
-
1496
- Selenium.prototype.getAllFields = function() {
1497
- /** Returns the IDs of all input fields on the page.
1498
- *
1499
- * <p>If a given field has no ID, it will appear as "" in this array.</p>
1500
- *
1501
- * @return string[] the IDs of all field on the page
1502
- */
1503
- return this.browserbot.getAllFields();
1504
- };
1505
-
1506
- Selenium.prototype.getAttributeFromAllWindows = function(attributeName) {
1507
- /** Returns every instance of some attribute from all known windows.
1508
- *
1509
- * @param attributeName name of an attribute on the windows
1510
- * @return string[] the set of values of this attribute from all known windows.
1511
- */
1512
- var attributes = new Array();
1513
-
1514
- var win = selenium.browserbot.topWindow;
1515
-
1516
- // DGF normally you should use []s instead of eval "win."+attributeName
1517
- // but in this case, attributeName may contain dots (e.g. document.title)
1518
- // in that case, we have no choice but to use eval...
1519
- attributes.push(eval("win."+attributeName));
1520
- for (var windowName in this.browserbot.openedWindows)
1521
- {
1522
- try {
1523
- win = selenium.browserbot.openedWindows[windowName];
1524
- attributes.push(eval("win."+attributeName));
1525
- } catch (e) {} // DGF If we miss one... meh. It's probably closed or inaccessible anyway.
1526
- }
1527
- return attributes;
1528
- };
1529
-
1530
- Selenium.prototype.findWindow = function(soughtAfterWindowPropertyValue) {
1531
- var targetPropertyName = "name";
1532
- if (soughtAfterWindowPropertyValue.match("^title=")) {
1533
- targetPropertyName = "document.title";
1534
- soughtAfterWindowPropertyValue = soughtAfterWindowPropertyValue.replace(/^title=/, "");
1535
- }
1536
- else {
1537
- // matching "name":
1538
- // If we are not in proxy injection mode, then the top-level test window will be named selenium_myiframe.
1539
- // But as far as the interface goes, we are expected to match a blank string to this window, if
1540
- // we are searching with respect to the widow name.
1541
- // So make a special case so that this logic will work:
1542
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, "")) {
1543
- return this.browserbot.getCurrentWindow();
1544
- }
1545
- }
1546
-
1547
- // DGF normally you should use []s instead of eval "win."+attributeName
1548
- // but in this case, attributeName may contain dots (e.g. document.title)
1549
- // in that case, we have no choice but to use eval...
1550
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("this.browserbot.topWindow." + targetPropertyName))) {
1551
- return this.browserbot.topWindow;
1552
- }
1553
- for (windowName in selenium.browserbot.openedWindows) {
1554
- var openedWindow = selenium.browserbot.openedWindows[windowName];
1555
- if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("openedWindow." + targetPropertyName))) {
1556
- return openedWindow;
1557
- }
1558
- }
1559
- throw new SeleniumError("could not find window with property " + targetPropertyName + " matching " + soughtAfterWindowPropertyValue);
1560
- };
1561
-
1562
- Selenium.prototype.doDragdrop = function(locator, movementsString) {
1563
- /** deprecated - use dragAndDrop instead
1564
- *
1565
- * @param locator an element locator
1566
- * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
1567
- */
1568
- this.doDragAndDrop(locator, movementsString);
1569
- };
1570
-
1571
- Selenium.prototype.doSetMouseSpeed = function(pixels) {
1572
- /** Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
1573
- * <p>Setting this value to 0 means that we'll send a "mousemove" event to every single pixel
1574
- * in between the start location and the end location; that can be very slow, and may
1575
- * cause some browsers to force the JavaScript to timeout.</p>
1576
- *
1577
- * <p>If the mouse speed is greater than the distance between the two dragged objects, we'll
1578
- * just send one "mousemove" at the start location and then one final one at the end location.</p>
1579
- * @param pixels the number of pixels between "mousemove" events
1580
- */
1581
- this.mouseSpeed = pixels;
1582
- }
1583
-
1584
- Selenium.prototype.getMouseSpeed = function() {
1585
- /** Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10).
1586
- *
1587
- * @return number the number of pixels between "mousemove" events during dragAndDrop commands (default=10)
1588
- */
1589
- this.mouseSpeed = pixels;
1590
- }
1591
-
1592
-
1593
- Selenium.prototype.doDragAndDrop = function(locator, movementsString) {
1594
- /** Drags an element a certain distance and then drops it
1595
- * @param locator an element locator
1596
- * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"
1597
- */
1598
- var element = this.browserbot.findElement(locator);
1599
- var clientStartXY = getClientXY(element)
1600
- var clientStartX = clientStartXY[0];
1601
- var clientStartY = clientStartXY[1];
1602
-
1603
- var movements = movementsString.split(/,/);
1604
- var movementX = Number(movements[0]);
1605
- var movementY = Number(movements[1]);
1606
-
1607
- var clientFinishX = ((clientStartX + movementX) < 0) ? 0 : (clientStartX + movementX);
1608
- var clientFinishY = ((clientStartY + movementY) < 0) ? 0 : (clientStartY + movementY);
1609
-
1610
- var mouseSpeed = this.mouseSpeed;
1611
- var move = function(current, dest) {
1612
- if (current == dest) return current;
1613
- if (Math.abs(current - dest) < mouseSpeed) return dest;
1614
- return (current < dest) ? current + mouseSpeed : current - mouseSpeed;
1615
- }
1616
-
1617
- this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientStartX, clientStartY);
1618
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientStartX, clientStartY);
1619
- var clientX = clientStartX;
1620
- var clientY = clientStartY;
1621
-
1622
- while ((clientX != clientFinishX) || (clientY != clientFinishY)) {
1623
- clientX = move(clientX, clientFinishX);
1624
- clientY = move(clientY, clientFinishY);
1625
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientX, clientY);
1626
- }
1627
-
1628
- this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientFinishX, clientFinishY);
1629
- this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientFinishX, clientFinishY);
1630
- };
1631
-
1632
- Selenium.prototype.doDragAndDropToObject = function(locatorOfObjectToBeDragged, locatorOfDragDestinationObject) {
1633
- /** Drags an element and drops it on another element
1634
- *
1635
- * @param locatorOfObjectToBeDragged an element to be dragged
1636
- * @param locatorOfDragDestinationObject an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged is dropped
1637
- */
1638
- var startX = this.getElementPositionLeft(locatorOfObjectToBeDragged);
1639
- var startY = this.getElementPositionTop(locatorOfObjectToBeDragged);
1640
-
1641
- var destinationLeftX = this.getElementPositionLeft(locatorOfDragDestinationObject);
1642
- var destinationTopY = this.getElementPositionTop(locatorOfDragDestinationObject);
1643
- var destinationWidth = this.getElementWidth(locatorOfDragDestinationObject);
1644
- var destinationHeight = this.getElementHeight(locatorOfDragDestinationObject);
1645
-
1646
- var endX = Math.round(destinationLeftX + (destinationWidth / 2));
1647
- var endY = Math.round(destinationTopY + (destinationHeight / 2));
1648
-
1649
- var deltaX = endX - startX;
1650
- var deltaY = endY - startY;
1651
-
1652
- var movementsString = "" + deltaX + "," + deltaY;
1653
-
1654
- this.doDragAndDrop(locatorOfObjectToBeDragged, movementsString);
1655
- };
1656
-
1657
- Selenium.prototype.doWindowFocus = function() {
1658
- /** Gives focus to the currently selected window
1659
- *
1660
- */
1661
- this.browserbot.getCurrentWindow().focus();
1662
- };
1663
-
1664
-
1665
- Selenium.prototype.doWindowMaximize = function() {
1666
- /** Resize currently selected window to take up the entire screen
1667
- *
1668
- */
1669
- var window = this.browserbot.getCurrentWindow();
1670
- if (window!=null && window.screen) {
1671
- window.moveTo(0,0);
1672
- window.resizeTo(screen.availWidth, screen.availHeight);
1673
- }
1674
- };
1675
-
1676
- Selenium.prototype.getAllWindowIds = function() {
1677
- /** Returns the IDs of all windows that the browser knows about.
1678
- *
1679
- * @return string[] the IDs of all windows that the browser knows about.
1680
- */
1681
- return this.getAttributeFromAllWindows("id");
1682
- };
1683
-
1684
- Selenium.prototype.getAllWindowNames = function() {
1685
- /** Returns the names of all windows that the browser knows about.
1686
- *
1687
- * @return string[] the names of all windows that the browser knows about.
1688
- */
1689
- return this.getAttributeFromAllWindows("name");
1690
- };
1691
-
1692
- Selenium.prototype.getAllWindowTitles = function() {
1693
- /** Returns the titles of all windows that the browser knows about.
1694
- *
1695
- * @return string[] the titles of all windows that the browser knows about.
1696
- */
1697
- return this.getAttributeFromAllWindows("document.title");
1698
- };
1699
-
1700
- Selenium.prototype.getHtmlSource = function() {
1701
- /** Returns the entire HTML source between the opening and
1702
- * closing "html" tags.
1703
- *
1704
- * @return string the entire HTML source
1705
- */
1706
- return this.browserbot.getDocument().getElementsByTagName("html")[0].innerHTML;
1707
- };
1708
-
1709
- Selenium.prototype.doSetCursorPosition = function(locator, position) {
1710
- /**
1711
- * Moves the text cursor to the specified position in the given input element or textarea.
1712
- * This method will fail if the specified element isn't an input element or textarea.
1713
- *
1714
- * @param locator an <a href="#locators">element locator</a> pointing to an input element or textarea
1715
- * @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.
1716
- */
1717
- var element = this.browserbot.findElement(locator);
1718
- if (element.value == undefined) {
1719
- Assert.fail("Element " + locator + " is not an input.");
1720
- }
1721
- if (position == -1) {
1722
- position = element.value.length;
1723
- }
1724
-
1725
- if( element.setSelectionRange && !browserVersion.isOpera) {
1726
- element.focus();
1727
- element.setSelectionRange(/*start*/position,/*end*/position);
1728
- }
1729
- else if( element.createTextRange ) {
1730
- triggerEvent(element, 'focus', false);
1731
- var range = element.createTextRange();
1732
- range.collapse(true);
1733
- range.moveEnd('character',position);
1734
- range.moveStart('character',position);
1735
- range.select();
1736
- }
1737
- }
1738
-
1739
- Selenium.prototype.getElementIndex = function(locator) {
1740
- /**
1741
- * Get the relative index of an element to its parent (starting from 0). The comment node and empty text node
1742
- * will be ignored.
1743
- *
1744
- * @param locator an <a href="#locators">element locator</a> pointing to an element
1745
- * @return number of relative index of the element to its parent (starting from 0)
1746
- */
1747
- var element = this.browserbot.findElement(locator);
1748
- var previousSibling;
1749
- var index = 0;
1750
- while ((previousSibling = element.previousSibling) != null) {
1751
- if (!this._isCommentOrEmptyTextNode(previousSibling)) {
1752
- index++;
1753
- }
1754
- element = previousSibling;
1755
- }
1756
- return index;
1757
- }
1758
-
1759
- Selenium.prototype.isOrdered = function(locator1, locator2) {
1760
- /**
1761
- * Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will
1762
- * not be considered ordered.
1763
- *
1764
- * @param locator1 an <a href="#locators">element locator</a> pointing to the first element
1765
- * @param locator2 an <a href="#locators">element locator</a> pointing to the second element
1766
- * @return boolean true if element1 is the previous sibling of element2, false otherwise
1767
- */
1768
- var element1 = this.browserbot.findElement(locator1);
1769
- var element2 = this.browserbot.findElement(locator2);
1770
- if (element1 === element2) return false;
1771
-
1772
- var previousSibling;
1773
- while ((previousSibling = element2.previousSibling) != null) {
1774
- if (previousSibling === element1) {
1775
- return true;
1776
- }
1777
- element2 = previousSibling;
1778
- }
1779
- return false;
1780
- }
1781
-
1782
- Selenium.prototype._isCommentOrEmptyTextNode = function(node) {
1783
- return node.nodeType == 8 || ((node.nodeType == 3) && !(/[^\t\n\r ]/.test(node.data)));
1784
- }
1785
-
1786
- Selenium.prototype.getElementPositionLeft = function(locator) {
1787
- /**
1788
- * Retrieves the horizontal position of an element
1789
- *
1790
- * @param locator an <a href="#locators">element locator</a> pointing to an element OR an element itself
1791
- * @return number of pixels from the edge of the frame.
1792
- */
1793
- var element;
1794
- if ("string"==typeof locator) {
1795
- element = this.browserbot.findElement(locator);
1796
- }
1797
- else {
1798
- element = locator;
1799
- }
1800
- var x = element.offsetLeft;
1801
- var elementParent = element.offsetParent;
1802
-
1803
- while (elementParent != null)
1804
- {
1805
- if(document.all)
1806
- {
1807
- if( (elementParent.tagName != "TABLE") && (elementParent.tagName != "BODY") )
1808
- {
1809
- x += elementParent.clientLeft;
1810
- }
1811
- }
1812
- else // Netscape/DOM
1813
- {
1814
- if(elementParent.tagName == "TABLE")
1815
- {
1816
- var parentBorder = parseInt(elementParent.border);
1817
- if(isNaN(parentBorder))
1818
- {
1819
- var parentFrame = elementParent.getAttribute('frame');
1820
- if(parentFrame != null)
1821
- {
1822
- x += 1;
1823
- }
1824
- }
1825
- else if(parentBorder > 0)
1826
- {
1827
- x += parentBorder;
1828
- }
1829
- }
1830
- }
1831
- x += elementParent.offsetLeft;
1832
- elementParent = elementParent.offsetParent;
1833
- }
1834
- return x;
1835
- };
1836
-
1837
- Selenium.prototype.getElementPositionTop = function(locator) {
1838
- /**
1839
- * Retrieves the vertical position of an element
1840
- *
1841
- * @param locator an <a href="#locators">element locator</a> pointing to an element OR an element itself
1842
- * @return number of pixels from the edge of the frame.
1843
- */
1844
- var element;
1845
- if ("string"==typeof locator) {
1846
- element = this.browserbot.findElement(locator);
1847
- }
1848
- else {
1849
- element = locator;
1850
- }
1851
-
1852
- var y = 0;
1853
-
1854
- while (element != null)
1855
- {
1856
- if(document.all)
1857
- {
1858
- if( (element.tagName != "TABLE") && (element.tagName != "BODY") )
1859
- {
1860
- y += element.clientTop;
1861
- }
1862
- }
1863
- else // Netscape/DOM
1864
- {
1865
- if(element.tagName == "TABLE")
1866
- {
1867
- var parentBorder = parseInt(element.border);
1868
- if(isNaN(parentBorder))
1869
- {
1870
- var parentFrame = element.getAttribute('frame');
1871
- if(parentFrame != null)
1872
- {
1873
- y += 1;
1874
- }
1875
- }
1876
- else if(parentBorder > 0)
1877
- {
1878
- y += parentBorder;
1879
- }
1880
- }
1881
- }
1882
- y += element.offsetTop;
1883
-
1884
- // Netscape can get confused in some cases, such that the height of the parent is smaller
1885
- // than that of the element (which it shouldn't really be). If this is the case, we need to
1886
- // exclude this element, since it will result in too large a 'top' return value.
1887
- if (element.offsetParent && element.offsetParent.offsetHeight && element.offsetParent.offsetHeight < element.offsetHeight)
1888
- {
1889
- // skip the parent that's too small
1890
- element = element.offsetParent.offsetParent;
1891
- }
1892
- else
1893
- {
1894
- // Next up...
1895
- element = element.offsetParent;
1896
- }
1897
- }
1898
- return y;
1899
- };
1900
-
1901
- Selenium.prototype.getElementWidth = function(locator) {
1902
- /**
1903
- * Retrieves the width of an element
1904
- *
1905
- * @param locator an <a href="#locators">element locator</a> pointing to an element
1906
- * @return number width of an element in pixels
1907
- */
1908
- var element = this.browserbot.findElement(locator);
1909
- return element.offsetWidth;
1910
- };
1911
-
1912
- Selenium.prototype.getElementHeight = function(locator) {
1913
- /**
1914
- * Retrieves the height of an element
1915
- *
1916
- * @param locator an <a href="#locators">element locator</a> pointing to an element
1917
- * @return number height of an element in pixels
1918
- */
1919
- var element = this.browserbot.findElement(locator);
1920
- return element.offsetHeight;
1921
- };
1922
-
1923
- Selenium.prototype.getCursorPosition = function(locator) {
1924
- /**
1925
- * Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers.
1926
- *
1927
- * <p>Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to
1928
- * 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>
1929
- * This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.
1930
- *
1931
- * @param locator an <a href="#locators">element locator</a> pointing to an input element or textarea
1932
- * @return number the numerical position of the cursor in the field
1933
- */
1934
- var element = this.browserbot.findElement(locator);
1935
- var doc = this.browserbot.getDocument();
1936
- var win = this.browserbot.getCurrentWindow();
1937
- if( doc.selection && !browserVersion.isOpera){
1938
- try {
1939
- var selectRange = doc.selection.createRange().duplicate();
1940
- var elementRange = element.createTextRange();
1941
- selectRange.move("character",0);
1942
- elementRange.move("character",0);
1943
- var inRange1 = selectRange.inRange(elementRange);
1944
- var inRange2 = elementRange.inRange(selectRange);
1945
- elementRange.setEndPoint("EndToEnd", selectRange);
1946
- } catch (e) {
1947
- Assert.fail("There is no cursor on this page!");
1948
- }
1949
- var answer = String(elementRange.text).replace(/\r/g,"").length;
1950
- return answer;
1951
- } else {
1952
- if (typeof(element.selectionStart) != "undefined") {
1953
- if (win.getSelection && typeof(win.getSelection().rangeCount) != undefined && win.getSelection().rangeCount == 0) {
1954
- Assert.fail("There is no cursor on this page!");
1955
- }
1956
- return element.selectionStart;
1957
- }
1958
- }
1959
- throw new Error("Couldn't detect cursor position on this browser!");
1960
- }
1961
-
1962
-
1963
- Selenium.prototype.getExpression = function(expression) {
1964
- /**
1965
- * Returns the specified expression.
1966
- *
1967
- * <p>This is useful because of JavaScript preprocessing.
1968
- * It is used to generate commands like assertExpression and waitForExpression.</p>
1969
- *
1970
- * @param expression the value to return
1971
- * @return string the value passed in
1972
- */
1973
- return expression;
1974
- }
1975
-
1976
- Selenium.prototype.getXpathCount = function(xpath) {
1977
- /**
1978
- * Returns the number of nodes that match the specified xpath, eg. "//table" would give
1979
- * the number of tables.
1980
- *
1981
- * @param xpath the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you.
1982
- * @return number the number of nodes that match the specified xpath
1983
- */
1984
- var result = this.browserbot.evaluateXPathCount(xpath, this.browserbot.getDocument());
1985
- return result;
1986
- }
1987
-
1988
- Selenium.prototype.doAssignId = function(locator, identifier) {
1989
- /**
1990
- * Temporarily sets the "id" attribute of the specified element, so you can locate it in the future
1991
- * using its ID rather than a slow/complicated XPath. This ID will disappear once the page is
1992
- * reloaded.
1993
- * @param locator an <a href="#locators">element locator</a> pointing to an element
1994
- * @param identifier a string to be used as the ID of the specified element
1995
- */
1996
- var element = this.browserbot.findElement(locator);
1997
- element.id = identifier;
1998
- }
1999
-
2000
- Selenium.prototype.doAllowNativeXpath = function(allow) {
2001
- /**
2002
- * Specifies whether Selenium should use the native in-browser implementation
2003
- * of XPath (if any native version is available); if you pass "false" to
2004
- * this function, we will always use our pure-JavaScript xpath library.
2005
- * Using the pure-JS xpath library can improve the consistency of xpath
2006
- * element locators between different browser vendors, but the pure-JS
2007
- * version is much slower than the native implementations.
2008
- * @param allow boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath
2009
- */
2010
- if ("false" == allow || "0" == allow) { // The strings "false" and "0" are true values in JS
2011
- allow = false;
2012
- }
2013
- this.browserbot.allowNativeXpath = allow;
2014
- }
2015
-
2016
- Selenium.prototype.doWaitForCondition = function(script, timeout) {
2017
- /**
2018
- * Runs the specified JavaScript snippet repeatedly until it evaluates to "true".
2019
- * The snippet may have multiple lines, but only the result of the last line
2020
- * will be considered.
2021
- *
2022
- * <p>Note that, by default, the snippet will be run in the runner's test window, not in the window
2023
- * of your application. To get the window of your application, you can use
2024
- * the JavaScript snippet <code>selenium.browserbot.getCurrentWindow()</code>, and then
2025
- * run your JavaScript in there</p>
2026
- * @param script the JavaScript snippet to run
2027
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2028
- */
2029
-
2030
- return Selenium.decorateFunctionWithTimeout(function () {
2031
- var window = selenium.browserbot.getCurrentWindow();
2032
- return eval(script);
2033
- }, timeout);
2034
- };
2035
-
2036
- Selenium.prototype.doWaitForCondition.dontCheckAlertsAndConfirms = true;
2037
-
2038
- Selenium.prototype.doSetTimeout = function(timeout) {
2039
- /**
2040
- * Specifies the amount of time that Selenium will wait for actions to complete.
2041
- *
2042
- * <p>Actions that require waiting include "open" and the "waitFor*" actions.</p>
2043
- * The default timeout is 30 seconds.
2044
- * @param timeout a timeout in milliseconds, after which the action will return with an error
2045
- */
2046
- if (!timeout) {
2047
- timeout = Selenium.DEFAULT_TIMEOUT;
2048
- }
2049
- this.defaultTimeout = timeout;
2050
- }
2051
-
2052
- Selenium.prototype.doWaitForPageToLoad = function(timeout) {
2053
- /**
2054
- * Waits for a new page to load.
2055
- *
2056
- * <p>You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc.
2057
- * (which are only available in the JS API).</p>
2058
- *
2059
- * <p>Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded"
2060
- * flag when it first notices a page load. Running any other Selenium command after
2061
- * turns the flag to false. Hence, if you want to wait for a page to load, you must
2062
- * wait immediately after a Selenium command that caused a page-load.</p>
2063
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2064
- */
2065
- // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded
2066
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
2067
- return this.makePageLoadCondition(timeout);
2068
- }
2069
- };
2070
-
2071
- Selenium.prototype.doWaitForFrameToLoad = function(frameAddress, timeout) {
2072
- /**
2073
- * Waits for a new frame to load.
2074
- *
2075
- * <p>Selenium constantly keeps track of new pages and frames loading,
2076
- * and sets a "newPageLoaded" flag when it first notices a page load.</p>
2077
- *
2078
- * See waitForPageToLoad for more information.
2079
- *
2080
- * @param frameAddress FrameAddress from the server side
2081
- * @param timeout a timeout in milliseconds, after which this command will return with an error
2082
- */
2083
- // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded
2084
- if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) {
2085
- return this.makePageLoadCondition(timeout);
2086
- }
2087
- };
2088
-
2089
- Selenium.prototype._isNewPageLoaded = function() {
2090
- return this.browserbot.isNewPageLoaded();
2091
- };
2092
-
2093
- Selenium.prototype.doWaitForPageToLoad.dontCheckAlertsAndConfirms = true;
2094
-
2095
- /**
2096
- * Evaluate a parameter, performing JavaScript evaluation and variable substitution.
2097
- * If the string matches the pattern "javascript{ ... }", evaluate the string between the braces.
2098
- */
2099
- Selenium.prototype.preprocessParameter = function(value) {
2100
- var match = value.match(/^javascript\{((.|\r?\n)+)\}$/);
2101
- if (match && match[1]) {
2102
- return eval(match[1]).toString();
2103
- }
2104
- return this.replaceVariables(value);
2105
- };
2106
-
2107
- /*
2108
- * Search through str and replace all variable references ${varName} with their
2109
- * value in storedVars.
2110
- */
2111
- Selenium.prototype.replaceVariables = function(str) {
2112
- var stringResult = str;
2113
-
2114
- // Find all of the matching variable references
2115
- var match = stringResult.match(/\$\{\w+\}/g);
2116
- if (!match) {
2117
- return stringResult;
2118
- }
2119
-
2120
- // For each match, lookup the variable value, and replace if found
2121
- for (var i = 0; match && i < match.length; i++) {
2122
- var variable = match[i]; // The replacement variable, with ${}
2123
- var name = variable.substring(2, variable.length - 1); // The replacement variable without ${}
2124
- var replacement = storedVars[name];
2125
- if (replacement != undefined) {
2126
- stringResult = stringResult.replace(variable, replacement);
2127
- }
2128
- }
2129
- return stringResult;
2130
- };
2131
-
2132
- Selenium.prototype.getCookie = function() {
2133
- /**
2134
- * Return all cookies of the current page under test.
2135
- *
2136
- * @return string all cookies of the current page under test
2137
- */
2138
- var doc = this.browserbot.getDocument();
2139
- return doc.cookie;
2140
- };
2141
-
2142
- Selenium.prototype.doCreateCookie = function(nameValuePair, optionsString) {
2143
- /**
2144
- * Create a new cookie whose path and domain are same with those of current page
2145
- * under test, unless you specified a path for this cookie explicitly.
2146
- *
2147
- * @param nameValuePair name and value of the cookie in a format "name=value"
2148
- * @param optionsString options for the cookie. Currently supported options include 'path' and 'max_age'.
2149
- * the optionsString's format is "path=/path/, max_age=60". The order of options are irrelevant, the unit
2150
- * of the value of 'max_age' is second.
2151
- */
2152
- var results = /[^\s=\[\]\(\),"\/\?@:;]+=[^\s=\[\]\(\),"\/\?@:;]*/.test(nameValuePair);
2153
- if (!results) {
2154
- throw new SeleniumError("Invalid parameter.");
2155
- }
2156
- var cookie = nameValuePair.trim();
2157
- results = /max_age=(\d+)/.exec(optionsString);
2158
- if (results) {
2159
- var expireDateInMilliseconds = (new Date()).getTime() + results[1] * 1000;
2160
- cookie += "; expires=" + new Date(expireDateInMilliseconds).toGMTString();
2161
- }
2162
- results = /path=([^\s,]+)[,]?/.exec(optionsString);
2163
- if (results) {
2164
- var path = results[1];
2165
- if (browserVersion.khtml) {
2166
- // Safari and conquerer don't like paths with / at the end
2167
- if ("/" != path) {
2168
- path = path.replace(/\/$/, "");
2169
- }
2170
- }
2171
- cookie += "; path=" + path;
2172
- }
2173
- LOG.debug("Setting cookie to: " + cookie);
2174
- this.browserbot.getDocument().cookie = cookie;
2175
- }
2176
-
2177
- Selenium.prototype.doDeleteCookie = function(name,path) {
2178
- /**
2179
- * Delete a named cookie with specified path.
2180
- *
2181
- * @param name the name of the cookie to be deleted
2182
- * @param path the path property of the cookie to be deleted
2183
- */
2184
- // set the expire time of the cookie to be deleted to one minute before now.
2185
- path = path.trim();
2186
- if (browserVersion.khtml) {
2187
- // Safari and conquerer don't like paths with / at the end
2188
- if ("/" != path) {
2189
- path = path.replace(/\/$/, "");
2190
- }
2191
- }
2192
- var expireDateInMilliseconds = (new Date()).getTime() + (-1 * 1000);
2193
- var cookie = name.trim() + "=deleted; path=" + path + "; expires=" + new Date(expireDateInMilliseconds).toGMTString();
2194
- LOG.debug("Setting cookie to: " + cookie);
2195
- this.browserbot.getDocument().cookie = cookie;
2196
- }
2197
-
2198
- Selenium.prototype.doSetBrowserLogLevel = function(logLevel) {
2199
- /**
2200
- * Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded.
2201
- * Valid logLevel strings are: "debug", "info", "warn", "error" or "off".
2202
- * To see the browser logs, you need to
2203
- * either show the log window in GUI mode, or enable browser-side logging in Selenium RC.
2204
- *
2205
- * @param logLevel one of the following: "debug", "info", "warn", "error" or "off"
2206
- */
2207
- if (logLevel == null || logLevel == "") {
2208
- throw new SeleniumError("You must specify a log level");
2209
- }
2210
- logLevel = logLevel.toLowerCase();
2211
- if (LOG.logLevels[logLevel] == null) {
2212
- throw new SeleniumError("Invalid log level: " + logLevel);
2213
- }
2214
- LOG.setLogLevelThreshold(logLevel);
2215
- }
2216
-
2217
- Selenium.prototype.doRunScript = function(script) {
2218
- /**
2219
- * Creates a new "script" tag in the body of the current test window, and
2220
- * adds the specified text into the body of the command. Scripts run in
2221
- * this way can often be debugged more easily than scripts executed using
2222
- * Selenium's "getEval" command. Beware that JS exceptions thrown in these script
2223
- * tags aren't managed by Selenium, so you should probably wrap your script
2224
- * in try/catch blocks if there is any chance that the script will throw
2225
- * an exception.
2226
- * @param script the JavaScript snippet to run
2227
- */
2228
- var win = this.browserbot.getCurrentWindow();
2229
- var doc = win.document;
2230
- var scriptTag = doc.createElement("script");
2231
- scriptTag.type = "text/javascript"
2232
- scriptTag.text = script;
2233
- doc.body.appendChild(scriptTag);
2234
- }
2235
-
2236
- Selenium.prototype.doAddLocationStrategy = function(strategyName, functionDefinition) {
2237
- /**
2238
- * Defines a new function for Selenium to locate elements on the page.
2239
- * For example,
2240
- * if you define the strategy "foo", and someone runs click("foo=blah"), we'll
2241
- * run your function, passing you the string "blah", and click on the element
2242
- * that your function
2243
- * returns, or throw an "Element not found" error if your function returns null.
2244
- *
2245
- * We'll pass three arguments to your function:
2246
- * <ul>
2247
- * <li>locator: the string the user passed in</li>
2248
- * <li>inWindow: the currently selected window</li>
2249
- * <li>inDocument: the currently selected document</li>
2250
- * </ul>
2251
- * The function must return null if the element can't be found.
2252
- *
2253
- * @param strategyName the name of the strategy to define; this should use only
2254
- * letters [a-zA-Z] with no spaces or other punctuation.
2255
- * @param functionDefinition a string defining the body of a function in JavaScript.
2256
- * For example: <code>return inDocument.getElementById(locator);</code>
2257
- */
2258
- if (!/^[a-zA-Z]+$/.test(strategyName)) {
2259
- throw new SeleniumError("Invalid strategy name: " + strategyName);
2260
- }
2261
- var strategyFunction;
2262
- try {
2263
- strategyFunction = new Function("locator", "inDocument", "inWindow", functionDefinition);
2264
- } catch (ex) {
2265
- throw new SeleniumError("Error evaluating function definition: " + extractExceptionMessage(ex));
2266
- }
2267
- var safeStrategyFunction = function() {
2268
- try {
2269
- return strategyFunction.apply(this, arguments);
2270
- } catch (ex) {
2271
- throw new SeleniumError("Error executing strategy function " + strategyName + ": " + extractExceptionMessage(ex));
2272
- }
2273
- }
2274
- this.browserbot.locationStrategies[strategyName] = safeStrategyFunction;
2275
- }
2276
-
2277
- /**
2278
- * Factory for creating "Option Locators".
2279
- * An OptionLocator is an object for dealing with Select options (e.g. for
2280
- * finding a specified option, or asserting that the selected option of
2281
- * Select element matches some condition.
2282
- * The type of locator returned by the factory depends on the locator string:
2283
- * label=<exp> (OptionLocatorByLabel)
2284
- * value=<exp> (OptionLocatorByValue)
2285
- * index=<exp> (OptionLocatorByIndex)
2286
- * id=<exp> (OptionLocatorById)
2287
- * <exp> (default is OptionLocatorByLabel).
2288
- */
2289
- function OptionLocatorFactory() {
2290
- }
2291
-
2292
- OptionLocatorFactory.prototype.fromLocatorString = function(locatorString) {
2293
- var locatorType = 'label';
2294
- var locatorValue = locatorString;
2295
- // If there is a locator prefix, use the specified strategy
2296
- var result = locatorString.match(/^([a-zA-Z]+)=(.*)/);
2297
- if (result) {
2298
- locatorType = result[1];
2299
- locatorValue = result[2];
2300
- }
2301
- if (this.optionLocators == undefined) {
2302
- this.registerOptionLocators();
2303
- }
2304
- if (this.optionLocators[locatorType]) {
2305
- return new this.optionLocators[locatorType](locatorValue);
2306
- }
2307
- throw new SeleniumError("Unkown option locator type: " + locatorType);
2308
- };
2309
-
2310
- /**
2311
- * To allow for easy extension, all of the option locators are found by
2312
- * searching for all methods of OptionLocatorFactory.prototype that start
2313
- * with "OptionLocatorBy".
2314
- * TODO: Consider using the term "Option Specifier" instead of "Option Locator".
2315
- */
2316
- OptionLocatorFactory.prototype.registerOptionLocators = function() {
2317
- this.optionLocators={};
2318
- for (var functionName in this) {
2319
- var result = /OptionLocatorBy([A-Z].+)$/.exec(functionName);
2320
- if (result != null) {
2321
- var locatorName = result[1].lcfirst();
2322
- this.optionLocators[locatorName] = this[functionName];
2323
- }
2324
- }
2325
- };
2326
-
2327
- /**
2328
- * OptionLocator for options identified by their labels.
2329
- */
2330
- OptionLocatorFactory.prototype.OptionLocatorByLabel = function(label) {
2331
- this.label = label;
2332
- this.labelMatcher = new PatternMatcher(this.label);
2333
- this.findOption = function(element) {
2334
- for (var i = 0; i < element.options.length; i++) {
2335
- if (this.labelMatcher.matches(element.options[i].text)) {
2336
- return element.options[i];
2337
- }
2338
- }
2339
- throw new SeleniumError("Option with label '" + this.label + "' not found");
2340
- };
2341
-
2342
- this.assertSelected = function(element) {
2343
- var selectedLabel = element.options[element.selectedIndex].text;
2344
- Assert.matches(this.label, selectedLabel)
2345
- };
2346
- };
2347
-
2348
- /**
2349
- * OptionLocator for options identified by their values.
2350
- */
2351
- OptionLocatorFactory.prototype.OptionLocatorByValue = function(value) {
2352
- this.value = value;
2353
- this.valueMatcher = new PatternMatcher(this.value);
2354
- this.findOption = function(element) {
2355
- for (var i = 0; i < element.options.length; i++) {
2356
- if (this.valueMatcher.matches(element.options[i].value)) {
2357
- return element.options[i];
2358
- }
2359
- }
2360
- throw new SeleniumError("Option with value '" + this.value + "' not found");
2361
- };
2362
-
2363
- this.assertSelected = function(element) {
2364
- var selectedValue = element.options[element.selectedIndex].value;
2365
- Assert.matches(this.value, selectedValue)
2366
- };
2367
- };
2368
-
2369
- /**
2370
- * OptionLocator for options identified by their index.
2371
- */
2372
- OptionLocatorFactory.prototype.OptionLocatorByIndex = function(index) {
2373
- this.index = Number(index);
2374
- if (isNaN(this.index) || this.index < 0) {
2375
- throw new SeleniumError("Illegal Index: " + index);
2376
- }
2377
-
2378
- this.findOption = function(element) {
2379
- if (element.options.length <= this.index) {
2380
- throw new SeleniumError("Index out of range. Only " + element.options.length + " options available");
2381
- }
2382
- return element.options[this.index];
2383
- };
2384
-
2385
- this.assertSelected = function(element) {
2386
- Assert.equals(this.index, element.selectedIndex);
2387
- };
2388
- };
2389
-
2390
- /**
2391
- * OptionLocator for options identified by their id.
2392
- */
2393
- OptionLocatorFactory.prototype.OptionLocatorById = function(id) {
2394
- this.id = id;
2395
- this.idMatcher = new PatternMatcher(this.id);
2396
- this.findOption = function(element) {
2397
- for (var i = 0; i < element.options.length; i++) {
2398
- if (this.idMatcher.matches(element.options[i].id)) {
2399
- return element.options[i];
2400
- }
2401
- }
2402
- throw new SeleniumError("Option with id '" + this.id + "' not found");
2403
- };
2404
-
2405
- this.assertSelected = function(element) {
2406
- var selectedId = element.options[element.selectedIndex].id;
2407
- Assert.matches(this.id, selectedId)
2408
- };
2409
- };