diff --git a/Gemfile b/Gemfile index fd25e38b..e4f5bdad 100644 --- a/Gemfile +++ b/Gemfile @@ -5,15 +5,15 @@ gem "rake", "~>0.8.7" gem "rails", "~>2.3.12" gem "highline", "~>1.5.0" gem "RedCloth", "4.2.3" -gem "soap4r" +gem "soap4r", "~>1.5.8" gem "sanitize", "~>1.2.1" gem "rack", "1.1.0" gem "will_paginate", "~> 2.3.15" gem "has_many_polymorphs", "~> 2.13" gem "acts_as_list", "~>0.1.4" -gem "aasm", "2.2.0" +gem "aasm", "~>2.2.0" gem "actionwebservice", :git => "git://github.com/dejan/actionwebservice.git" -gem "rubycas-client" +gem "rubycas-client", "~>2.2.1" gem "ruby-openid", :require => "openid" gem "sqlite3" gem 'bcrypt-ruby', '~> 2.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 1831cfdd..a952d7a4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,7 +96,7 @@ PLATFORMS DEPENDENCIES RedCloth (= 4.2.3) ZenTest (>= 4.0.0) - aasm (= 2.2.0) + aasm (~> 2.2.0) actionwebservice! acts_as_list (~> 0.1.4) bcrypt-ruby (~> 2.1.4) @@ -114,10 +114,10 @@ DEPENDENCIES rake (~> 0.8.7) rspec-rails (~> 1.3.3) ruby-openid - rubycas-client + rubycas-client (~> 2.2.1) sanitize (~> 1.2.1) selenium-client - soap4r + soap4r (~> 1.5.8) sqlite3 thoughtbot-factory_girl webrat (>= 0.7.0) diff --git a/config/environments/test.rb b/config/environments/test.rb index 1bddd2ed..2b031cb9 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -23,7 +23,7 @@ config.action_controller.allow_forgery_protection = false config.action_controller.session_store = :cookie_store config.action_controller.session = { :key => 'TracksTest', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil } -# Overwrite the default settings for fixtures in tests. See Fixtures +# Overwrite the default settings for fixtures in tests. See Fixtures # for more details about these settings. # config.transactional_fixtures = true # config.instantiated_fixtures = false @@ -31,8 +31,3 @@ config.action_controller.session = { :key => 'TracksTest', :secret => SITE_CONFI SITE_CONFIG['salt'] ||= 'change-me' config.time_zone = 'UTC' - -config.after_initialize do - require File.expand_path(File.dirname(__FILE__) + "/../../test/selenium_helper") -end - diff --git a/features/project_edit.feature b/features/project_edit.feature index d98c1ecc..e1877409 100644 --- a/features/project_edit.feature +++ b/features/project_edit.feature @@ -41,6 +41,24 @@ Feature: Edit a project And I edit the project name to "cherries" Then the project title should be "cherries" + @selenium @wip + Scenario: I can change the name of the project and it should update the new todo form + Given I have a project "bananas" with 1 todos + When I go to the "bananas" project + And I edit the project name to "cherries" + Then the project title should be "cherries" + And the project field of the new todo form should contain "cherries" + + @selenium @wip + Scenario: I can change the default context of the project and it should update the new todo form + Given I have a project "bananas" with 1 todos + When I go to the "bananas" project + And I edit the default context to "@pc" + Then the default context of the new todo form should be "@pc" + # the default context should be prefilled ater submitting a new todo + When I submit a new action with description "test" + Then the default context of the new todo form should be "@pc" + # Ticket #1042 @selenium Scenario: I cannot change the name of a project in the project view to the name of another existing project @@ -92,21 +110,29 @@ Feature: Edit a project When I cancel the project edit form Then I should see "This project is active with no default context and with no default tags" - @selenium - Scenario: Moving the todo to the tickler will move todo to tickler container + @selenium @wip + Scenario: Moving the todo to the tickler will move todo to tickler container and update empty messages Given I have a project "test" with 1 todos When I go to the "test" project Then I should see "todo 1" in the action container + And I should see "Currently there are no deferred actions in this project" + And I should not see "Currently there are no incomplete actions in this project" When I defer "todo 1" for 1 day Then I should see "todo 1" in the deferred container + And I should not see "Currently there are no deferred actions in this project" + And I should see "Currently there are no incomplete actions in this project" - @selenium - Scenario: Moving the todo out of the tickler will move todo to active container - Given I have a project "test" with 1 todos + @selenium @wip + Scenario: Moving the todo out of the tickler will move todo to active container and update empty messages + Given I have a project "test" with 1 deferred todos When I go to the "test" project - Then I should see "todo 1" in the action container - When I defer "todo 1" for 1 day Then I should see "todo 1" in the deferred container + And I should see "Currently there are no incomplete actions in this project" + And I should not see "Currently there are no deferred actions in this project" + When I defer "todo 1" for 1 day + Then I should see "todo 1" in the active container + And I should see "Currently there are no deferred actions in this project" + And I should not see "Currently there are no incomplete actions in this project" @selenium Scenario: Making all todos inactive will show empty message @@ -115,6 +141,13 @@ Feature: Edit a project And I mark "todo 1" as complete Then I should see "Currently there are no incomplete actions in this project" + @selenium @wip + Scenario: Making all deferred todos inactive will show empty message + Given I have a project "test" with 1 deferred todos + When I go to the "test" project + And I mark "todo 1" as complete + Then I should see "Currently there are no incomplete actions in this project" + # Ticket #1043 @selenium Scenario: I can move a todo out of the current project diff --git a/features/tagging_todos.feature b/features/tagging_todos.feature index 04ced4c0..e3d8688d 100644 --- a/features/tagging_todos.feature +++ b/features/tagging_todos.feature @@ -11,6 +11,11 @@ Feature: Tagging todos And I have a context called "@pc" And I have a project called "hacking tracks" + @wip + Scenario: If there are no todos with a tag, the tag page should show an empty message + When I go to the tag page for "starred" + Then I should see "Currently there are no incomplete actions with the tag 'starred'" + @selenium Scenario: I can remove a tag from a todo from the tag view and the todo will be removed Given I have a todo "fix tests" in context "@pc" with tags "now" @@ -49,4 +54,26 @@ Feature: Tagging todos Then I should see "prepare release" in the context container for "@pc" When I edit the context of "prepare release" to "@secret" Then I should not see "prepare release" in the context container for "@pc" - Then I should see "prepare release" in the hidden container \ No newline at end of file + Then I should see "prepare release" in the hidden container + + @selenium @wip + Scenario: Completing the last todo from the tag view will show the empty message + Given I have a todo "migrate old scripts" in context "@pc" with tags "starred" + When I go to the tag page for "starred" + Then I should see "migrate old scripts" in the context container for "@pc" + When I mark "migrate old scripts" as complete + Then I should not see the context container for "@pc" + And I should see "Currently there are no incomplete actions with the tag 'starred'" + + @selenium @wip + Scenario: Setting default tags for a project will prefill new todo form for that project + When I go to the project page for "hacking tracks" + Then the tag field in the new todo form should be empty + And I edit the default tags to "tests" + Then the tag field in the new todo form should be "tests" + # also the tag field should be prefilled after reload + When I go to the project page for "hacking tracks" + Then the tag field in the new todo form shoudl be "tests" + # and the tag field should be prefilled after submitting a new todo + When I submit a new action with description "are my tags prefilled" + Then the tags of "are my tags prefilled" should be "tests" \ No newline at end of file diff --git a/lib/selenium_driver_manager.rb b/lib/selenium_driver_manager.rb deleted file mode 100644 index 5019ba3c..00000000 --- a/lib/selenium_driver_manager.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'singleton' -require 'selenium' - -class SeleniumDriverManager - include Singleton - - def running_selenium_driver - start - driver - end - - def start - return if running? - driver.start - @running = true - end - - def stop - return unless running? - driver.stop - @running = false - end - - def running? - @running - end - - protected - - def driver - @driver ||= Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", "http://localhost", 15000) - end - -end diff --git a/test/selenium/home/create_first_todo.rsel b/test/selenium/home/create_first_todo.rsel deleted file mode 100644 index 5a52f41f..00000000 --- a/test/selenium/home/create_first_todo.rsel +++ /dev/null @@ -1,9 +0,0 @@ -setup :fixtures => :users, :clear_tables => [:projects, :contexts, :todos] -login :as => 'admin' -open "/" -assert_context_count_incremented do - type "todo_description", "a new action" - type "todo_context_name", "Brand new context" - click "css=#todo-form-new-action .submit_box button" - assert_confirmation "New context 'Brand new context' will be also created. Are you sure?" -end diff --git a/test/selenium/home/create_new_todo_in_context_and_hide_context.rsel b/test/selenium/home/create_new_todo_in_context_and_hide_context.rsel deleted file mode 100644 index 8e540225..00000000 --- a/test/selenium/home/create_new_todo_in_context_and_hide_context.rsel +++ /dev/null @@ -1,24 +0,0 @@ -# adding a new action to context and collapsing context should remove -# all actions in context including the newly added one - -setup :fixtures => :all -login :as => 'admin' -open "/" - -assert_element_present "todo_9" - -# add new action to existing context -type "todo_description", "a new action" -type "todo_context_name", "agenda" -click "css=#todo-form-new-action .submit_box button" -wait_for_visible "flash" - -# toggle Agenda context c1 and wait until the context has collapsed -click "css=#toggle_c1" -wait_for_not_visible "todo_9" - -# check that newly added action is not there -wait_for_not_visible "xpath=//span[text()='a new action']" - -# toggle c1 back. Selenium does not reset cookies -click "css=#toggle_c1" diff --git a/test/selenium/home/create_todo_in_completed_project.rsel b/test/selenium/home/create_todo_in_completed_project.rsel deleted file mode 100644 index dbec9a86..00000000 --- a/test/selenium/home/create_todo_in_completed_project.rsel +++ /dev/null @@ -1,34 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' - -open "/" -# we should start with 10 actions on home page -assert_text 'badge_count', '11' - -# set project to hidden state -open "/projects/2" -click 'css=.project_settings a' -wait_for_visible "project_state_completed" -click 'project_state_completed' -click 'submit_project_2' -# wait for flash before navigating away from project page -wait_for_visible "flash" - -# monitor badge count on home page. It should be 7 at the start -open "/" -wait_for_visible 'badge_count' -assert_text 'badge_count', '7' - -# add todo to hidden project -type "todo_description", "should be hidden" -type "todo_project_name", "Make more money than Billy Gates" -type "todo_context_name", "agenda" -click "css=#todo-form-new-action .submit_box button" - -# wait for flash to appear -wait_for_visible "flash" - -verify_text_not_present 'should be hidden' - -# badge count should still be same -assert_text 'badge_count', '7' diff --git a/test/selenium/home/create_todo_in_hidden_project.rsel b/test/selenium/home/create_todo_in_hidden_project.rsel deleted file mode 100644 index c86ed494..00000000 --- a/test/selenium/home/create_todo_in_hidden_project.rsel +++ /dev/null @@ -1,30 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' - -# set project to hidden state -open "/projects/2" -click 'css=.project_settings a' -wait_for_visible "project_state_hidden" -click 'project_state_hidden' -click 'submit_project_2' -# wait for flash before navigating away from project page to make sure that -# the changes have been saved -wait_for_visible "flash" - -# monitor badge count on home page. It should be 7 at the start -open "/" -assert_text 'badge_count', '7' - -# add todo to hidden project -type "todo_description", "should be hidden" -type "todo_project_name", "Make more money than Billy Gates" -type "todo_context_name", "agenda" -click "css=#todo-form-new-action .submit_box button" - -# wait for flash to (dis)appear -wait_for_visible "flash" - -verify_text_not_present 'should be hidden' - -# badge count should still be same -assert_text 'badge_count', '7' diff --git a/test/selenium/home/delete_todo_empty_context.rsel b/test/selenium/home/delete_todo_empty_context.rsel deleted file mode 100644 index d3dca914..00000000 --- a/test/selenium/home/delete_todo_empty_context.rsel +++ /dev/null @@ -1,7 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/" -wait_for_element_present '//div[@id="line_todo_5"]//img[@alt="Delete"]/..' -click '//div[@id="line_todo_5"]//img[@alt="Delete"]/..' -assert_confirmation "Are you sure that you want to delete the action 'Construct time dilation device'?" -wait_for_not_visible "c5" diff --git a/test/selenium/home/mark_todo_complete_2.rsel b/test/selenium/home/mark_todo_complete_2.rsel deleted file mode 100644 index fc1fa394..00000000 --- a/test/selenium/home/mark_todo_complete_2.rsel +++ /dev/null @@ -1,6 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open '/' -click "xpath=//div[@id='c5'] //div[@id='todo_5'] //input[@class='item-checkbox']" -wait_for_element_present "xpath=//div[@id='completed_container'] //div[@id='todo_5']" -wait_for_not_visible 'c5' diff --git a/test/selenium/home/mark_todo_incomplete.rsel b/test/selenium/home/mark_todo_incomplete.rsel deleted file mode 100644 index 150d7a0f..00000000 --- a/test/selenium/home/mark_todo_incomplete.rsel +++ /dev/null @@ -1,6 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open '/' -click "xpath=//div[@id='completed_container'] //div[@id='todo_3'] //input[@class='item-checkbox']" -wait_for_element_present "xpath=//div[@id='c4'] //div[@id='todo_3']" -wait_for_not_visible "c4empty-nd" diff --git a/test/selenium/login/_cas_first_admin.rsel b/test/selenium/login/_cas_first_admin.rsel deleted file mode 100644 index c4291cec..00000000 --- a/test/selenium/login/_cas_first_admin.rsel +++ /dev/null @@ -1,7 +0,0 @@ -open :controller => 'login' -type "username", username -type "password", password -click "//input[@value='Login']" -wait_for_page_to_load "30000" -click "signup" -wait_for_page_to_load "30000" diff --git a/test/selenium/login/_cas_first_normal_user.rsel b/test/selenium/login/_cas_first_normal_user.rsel deleted file mode 100644 index 6c5d4da6..00000000 --- a/test/selenium/login/_cas_first_normal_user.rsel +++ /dev/null @@ -1,11 +0,0 @@ -open :controller => 'login' -click "link=Login" -wait_for_page_to_load "30000" -type "username", username -type "password", password -click "//input[@value='Login']" -wait_for_page_to_load "30000" -click "link=Request Account" -wait_for_page_to_load "30000" -click "signup" -wait_for_page_to_load "30000" \ No newline at end of file diff --git a/test/selenium/login/_cas_normal_user_login.rsel b/test/selenium/login/_cas_normal_user_login.rsel deleted file mode 100644 index 7e31079c..00000000 --- a/test/selenium/login/_cas_normal_user_login.rsel +++ /dev/null @@ -1,6 +0,0 @@ -open :controller => 'login' -click "link=Login" -wait_for_page_to_load "30000" -type "username", username -type "password", password -click "//input[@value='Login']" diff --git a/test/selenium/login/_login.rsel b/test/selenium/login/_login.rsel deleted file mode 100644 index 2ba7b163..00000000 --- a/test/selenium/login/_login.rsel +++ /dev/null @@ -1,5 +0,0 @@ -open :controller => 'login', :action => 'logout' -open :controller => 'login' -type "user_login", username -type "user_password", password -click_and_wait "login" \ No newline at end of file diff --git a/test/selenium/project_detail/activate_deferred_todo.rsel b/test/selenium/project_detail/activate_deferred_todo.rsel deleted file mode 100644 index de13a668..00000000 --- a/test/selenium/project_detail/activate_deferred_todo.rsel +++ /dev/null @@ -1,20 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' - -#first, defer a todo -open "/projects/1" -click "edit_icon_todo_5" -wait_for_element_present "show_from_todo_5" -type "show_from_todo_5", "1/1/2030" -click "css=#submit_todo_5" -wait_for_element_present "xpath=//div[@id='tickler'] //div[@id='todo_5']" - -#now activate the other deferred one -open "/projects/1" -click "edit_icon_todo_15" -wait_for_element_present "show_from_todo_15" -type "show_from_todo_15", "" -click "css=#submit_todo_15" -wait_for_element_present "xpath=//div[@id='p1items'] //div[@id='todo_15']" -assert_not_visible "tickler-empty-nd" -assert_text 'badge_count', '2' diff --git a/test/selenium/project_detail/activate_last_deferred_todo.rsel b/test/selenium/project_detail/activate_last_deferred_todo.rsel deleted file mode 100644 index 31bbc6ab..00000000 --- a/test/selenium/project_detail/activate_last_deferred_todo.rsel +++ /dev/null @@ -1,9 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/1" -click "edit_icon_todo_15" -wait_for_element_present "show_from_todo_15" -type "show_from_todo_15", "" -click "css=#submit_todo_15" -wait_for_element_present "xpath=//div[@id='p1items'] //div[@id='todo_15']" -wait_for_visible "tickler-empty-nd" diff --git a/test/selenium/project_detail/change_default_context.rsel b/test/selenium/project_detail/change_default_context.rsel deleted file mode 100644 index 984752c3..00000000 --- a/test/selenium/project_detail/change_default_context.rsel +++ /dev/null @@ -1,26 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/2" - -click 'css=.project_settings a' -wait_for_visible "project[default_context_name]" - -# change default context -type "project[default_context_name]", "errand" -click "css=.positive" - -wait_for_visible "flash" - -# add actions -type "todo_description", "test1" -click "css=#todo-form-new-action .submit_box button" - -wait_for_visible "flash" - -type "todo_description", "test2" -click "css=#todo-form-new-action .submit_box button" -wait_for_visible "flash" - -# check that context errand now contains 2 todos -open "/contexts/4" -assert_text "badge_count", "2" diff --git a/test/selenium/project_detail/changing_project_name_should_change_default_project.rsel b/test/selenium/project_detail/changing_project_name_should_change_default_project.rsel deleted file mode 100644 index d42d74d3..00000000 --- a/test/selenium/project_detail/changing_project_name_should_change_default_project.rsel +++ /dev/null @@ -1,13 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/1" - -# change project name -click "project_name" -wait_for_element_present "css=#project_name form input" -type "css=#project_name form input", "Test Foo" -click "css=#project_name form button" -wait_for_text "project_name", "Test Foo" - -# check that the default project name is changed too -wait_for_value "todo_project_name", "Test Foo" diff --git a/test/selenium/project_detail/mark_deferred_todo_complete.rsel b/test/selenium/project_detail/mark_deferred_todo_complete.rsel deleted file mode 100644 index 0b07d445..00000000 --- a/test/selenium/project_detail/mark_deferred_todo_complete.rsel +++ /dev/null @@ -1,7 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/1" -include_partial 'project_detail/add_deferred_todo' -click "xpath=//div[@id='tickler'] //div[@id='todo_15'] //input[@class='item-checkbox']" -wait_for_element_present "xpath=//div[@id='completed_container'] //div[@id='todo_15']" -assert_not_visible "tickler-empty-nd" \ No newline at end of file diff --git a/test/selenium/project_detail/mark_last_deferred_todo_complete.rsel b/test/selenium/project_detail/mark_last_deferred_todo_complete.rsel deleted file mode 100644 index 8ba271c8..00000000 --- a/test/selenium/project_detail/mark_last_deferred_todo_complete.rsel +++ /dev/null @@ -1,5 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/1" -click "xpath=//div[@id='tickler'] //div[@id='todo_15'] //input[@class='item-checkbox']" -wait_for_visible "tickler-empty-nd" diff --git a/test/selenium/project_detail/prefill_default_tags.rsel b/test/selenium/project_detail/prefill_default_tags.rsel deleted file mode 100644 index 10a83746..00000000 --- a/test/selenium/project_detail/prefill_default_tags.rsel +++ /dev/null @@ -1,16 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' - -#first, defer a todo -open "/projects/1" -click 'css=.project_settings a' -wait_for_visible "project[default_context_name]" -type "project_default_tags", "atag" -click 'css=.positive' -wait_for_value "tag_list", "atag" -open "/projects/1" -assert_value "tag_list", "atag" -type "todo_description", "a new task" -type "tag_list", "foo" -click "todo_new_action_submit" -wait_for_value "tag_list", "atag" diff --git a/test/selenium/tags/complete_last_todo.rsel b/test/selenium/tags/complete_last_todo.rsel deleted file mode 100644 index ee3be43f..00000000 --- a/test/selenium/tags/complete_last_todo.rsel +++ /dev/null @@ -1,7 +0,0 @@ -#Test for issue #952 -setup :fixtures => :all -login :as => 'admin' -open "/todos/tag/foo" -click "css=#line_todo_2 .item-checkbox" -wait_for_element_not_present "css=#c2 #line_todo_2" -wait_for_not_visible "c2" diff --git a/test/selenium/tags/open_starred_tags_without_anything_starred.rsel b/test/selenium/tags/open_starred_tags_without_anything_starred.rsel deleted file mode 100644 index 6aaf5812..00000000 --- a/test/selenium/tags/open_starred_tags_without_anything_starred.rsel +++ /dev/null @@ -1,6 +0,0 @@ -setup :fixtures => [:users, :projects, :contexts, :todos, :notes] -login :as => 'admin' -open "/" -click_and_wait "xpath=//a[@title='See your starred actions']" -assert_title "exact:TRACKS::Tagged with 'starred'" -verify_text_present "Currently there are no incomplete actions with the tag 'starred'" diff --git a/test/selenium_helper.rb b/test/selenium_helper.rb deleted file mode 100644 index 340af422..00000000 --- a/test/selenium_helper.rb +++ /dev/null @@ -1,67 +0,0 @@ -class SeleniumHelperController < ActionController::Base - def login - if params[:as] - user = User.find_by_login(params[:as].to_s) - session['user_id'] = user - user.contexts.each do |c| - cookies["tracks_#{user.login}_context_c#{c.id}_collapsed"] = nil - end - end - - render :text => "Logged in as #{params[:as]}" - end -end - -module SeleniumOnRails::TestBuilderActions - def login options = {} - options = {options => nil} unless options.is_a? Hash - opts = {:controller => 'selenium_helper', :action => 'login'}.merge(options) - open opts - end -end - -# The accessors available for SeleniumOnRails::TestBuilder tests. -# -# For each +store_foo+ there's +assert_foo+, +assert_not_foo+, +verify_foo+, -# +verify_not_foo+, +wait_for_foo+, +wait_for_not_foo+. -module SeleniumOnRails::TestBuilderAccessors - - # How many elements with the class "context" are present on the page? - # - # Related Assertions, automatically generated: - # * +assert_context_count+ - # * +assert_not_context_count+ - # * +verify_context_count+ - # * +verify_not_context_count+ - # * +wait_for_context_count+ - # * +wait_for_not_context_count+ - def store_context_count variable_name - command 'storeContextCount', variable_name - end - - each_assertion 'store_context_count' do |assertion_method, command_name| - define_method assertion_method do |expected_count| - command command_name, expected_count - end - end - - def drag_todo_to(id1, id2) - mouse_down_at "css=#line_todo_#{id1} img.grip", "4,4" - mouse_move_at "line_todo_#{id2}", '20,3' - mouse_over "line_todo_#{id2}" - mouse_up_at "line_todo_#{id2}", '20,3' - end - - def assert_context_count_incremented(&block) - store_context_count 'initial_context_count' - store_eval "${initial_context_count} + 1", 'expected_context_count' - yield - wait_for_context_count "${expected_context_count}" - end - - def click_and_wait clickable - click clickable - wait_for_page_to_load 3000 - end - -end diff --git a/vendor/plugins/selenium-on-rails/CHANGELOG b/vendor/plugins/selenium-on-rails/CHANGELOG deleted file mode 100644 index fa34aaf9..00000000 --- a/vendor/plugins/selenium-on-rails/CHANGELOG +++ /dev/null @@ -1,125 +0,0 @@ -== REVISION 38[http://svn.openqa.org/fisheye/changelog/selenium-on-rails/?cs=38] - -=== change made by Flanagan - -* SOR-13[http://jira.openqa.org/browse/SOR-13] Corrected an omission of require statements. - -== REVISION 37 - -=== change made by Flanagan - -* Undone an unwanted commit of modified Rakefile. - -== REVISION 36[http://svn.openqa.org/fisheye/changelog/selenium-on-rails/?cs=36] - -=== change made by Flanagan - -* SOR-13[http://jira.openqa.org/browse/SOR-13] Added (experimental) support for user-extensions.js. - -== REVISION 35[http://svn.openqa.org/fisheye/changelog/selenium-on-rails/?cs=35] - -=== all changes made by Jonas - -* SOR-12[http://jira.openqa.org/browse/SOR-12] removed all support for selenium gem -* Selenium Core 0.8.2 is now bundled with Selenium on Rails. If you want to use other version set the 'selenium_path' in config.yml -* Updated installation instructions for Windows - -== REVISION 34[http://svn.openqa.org/fisheye/changelog/selenium-on-rails/?cs=34] - -=== all changes made by Flanagan - -* SOR-11[http://jira.openqa.org/browse/SOR-11] Fixed related assertions for store_checked to use only locator parameter - -Warning: Users must change tests that pass two parameters (locator, pattern) to +verify_checked+, +verify_not_checked+, +assert_checked+, +assert_not_checked+, +wait_for_checked+, or +wait_for_not_checked+. - -Test scripts that continue to use two parameters will be broken, only one parameter, the locator, should be passed. - -For example, |verify_checked|my_checkbox|true| will be interpreted as |verify_checked|my_checkboxtrue|| so change the test to |verify_checked|my_checkbox|| - -* SOR-9[http://jira.openqa.org/browse/SOR-9] Added Mac OS X browsers to config.yml.example -* SOR-10[http://jira.openqa.org/browse/SOR-10] Added support for baseUrl to acceptance_test_runner.rb as added to selenium-core 0.8.2 -* Added 'webrick' to SERVER_COMMAND in acceptance_test_runner.rb as parameters do not work with lighttpd -* Reversed expected query string in test/renderer_testrb to make tests pass - -Note: On Mac OS X, at least, clear_tables comes before fixtures in the query string; this may be an environment-specific issue if the test now fails on other OSes. - -* Added this CHANGELOG file and amended the rake rdoc task to include it - -* Added support in rselenese for a long list of actions and accessors that are included in selenium-core (0.8.2 and possibly earlier) but were previously missing in selenium-on-rails. - -Here are the newly supported actions: - -Useful for debugging: -* brake (alias for selenium-core's break, a reserved word in Ruby) -* echo, :string -* highlight, :locator - -Keyboard events: -* alt_key_down -* alt_key_up -* control_key_down -* control_key_up -* meta_key_down -* meta_key_up -* shift_key_down -* shift_key_up -* type_keys, :locator, :string - -Mouse events: -* click_at, :locator, :coord_string -* double_click, :locator -* double_click_at, :locator, :coord_string -* drag_and_drop, :locator, :movements_string -* drag_and_drop_to_object, :locator, :locator -* mouse_down_at, :locator, :coord_string -* mouse_move, :locator -* mouse_move_at, :locator, :coord_string -* mouse_out, :locator -* mouse_up, :locator -* mouse_up_at, :locator, :coord_string -* set_mouse_speed, :integer - -Other actions: -* create_cookie, :name_value_pair, :options_string -* delete_cookie, :string, :string -* open_window, :url, :integer -* pause, :timeout -* remove_all_selections, :locator -* select_frame, :locator -* set_cursor_position, :locator, :integer -* store, :script, :variable -* window_focus, :window_name -* window_maximize, :window_name - -Here are the newly supported accessors: - -The following store_* accessors and their associated assert, verify and wait_for brethren are fully supported: -* store_selected_id, :locator, :variable -* store_selected_ids, :locator, :variable -* store_selected_index, :locator, :variable -* store_selected_indexes, :locator, :variable -* store_selected_label, :locator, :variable -* store_selected_labels, :locator, :variable -* store_selected_value, :locator, :variable -* store_selected_values, :locator, :variable -* store_something_selected, :locator, :variable -* store_all_window_ids, :variable -* store_all_window_names, :variable -* store_all_window_titles, :variable -* store_cookie, :variable -* store_log_messages, :variable -* store_mouse_speed, :variable -* store_cursor_position, :locator, :variable -* store_attribute_from_all_windows, :attribute_name, :variable -* store_element_height, :locator, :variable -* store_element_index, :locator, :variable -* store_element_width, :locator, :variable -* store_element_position_left, :locator, :variable -* store_element_position_top, :locator, :variable - -Only the associated assert, verify and wait_for brethren of the following store_* accessors are supported by the selenium-core, so these store_* accessors create exceptions in SOR: -* store_ordered, :locator, :locator, :variable -* store_error_on_next, :string -* store_failure_on_next, :string -* store_whether_this_frame_match_frame_expression, :string, :string, :variable -* store_whether_this_window_match_window_expression, :string, :string, :variable diff --git a/vendor/plugins/selenium-on-rails/LICENSE-2.0.txt b/vendor/plugins/selenium-on-rails/LICENSE-2.0.txt deleted file mode 100644 index d6456956..00000000 --- a/vendor/plugins/selenium-on-rails/LICENSE-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/plugins/selenium-on-rails/README.md b/vendor/plugins/selenium-on-rails/README.md deleted file mode 100644 index 58638a6b..00000000 --- a/vendor/plugins/selenium-on-rails/README.md +++ /dev/null @@ -1,202 +0,0 @@ -Welcome to the Selenium on Rails README. Exciting isn't it? - -# Selenium on Rails # - -## Overview ## - -Selenium on Rails provides an easy way to test Rails application with -SeleniumCore[http://www.openqa.org/selenium-core/]. - -This plugin does four things: - -1. The Selenium Core files don't have to pollute /public. -2. No need to create suite files, they are generated on the fly -- one suite per directory in /test/selenium (suites can be nested). -3. Instead of writing the test cases in HTML you can use a number of better formats (see Formats). -4. Loading of fixtures and wiping of session (/selenium/setup). - -## Installation ## - -Rails periodically changes the way that it renders pages, which unfortunately breaks backwards versions of Selenium on Rails. Therefore there are different -installation locations depending on your version of Rails: - -*Rails 2.2 and up:* - - http://svn.openqa.org/svn/selenium-on-rails/stable/selenium-on-rails - - -*Rails 2.1:* - - http://svn.openqa.org/svn/selenium-on-rails/tags/rails_2_1/selenium-on-rails - - -*Before Rails 2.1:* - - http://svn.openqa.org/svn/selenium-on-rails/tags/pre-rails-2-1/selenium-on-rails - - -The latest release is always kept on GitHub at - - git clone git://github.com/paytonrules/selenium-on-rails.git - - -To install: - -1. Install Selenium on Rails: script/plugin install -2. If you‘re on Windows, gem install win32-open3 -3. If the RedCloth gem is available the Selenese test cases can use it for better markup. -4. Run the Rakefile in the plugin‘s directory to run the tests in order to see that everything works. (If RedCloth isn‘t installed a few tests will fail since they assume RedCloth is installed.) -5. Create a test case: script/generate selenium -6. Start the server: script/server -e test -7. Point your browser to localhost:3000/selenium -8. If everything works as expected you should see the Selenium test runner. The north east frame contains all your test cases (just one for now), and the north frame contains your test case. - -## Formats ## - -The test cases can be written in a number of formats. Which one you choose is a matter of taste. You can generate your test files by running script/generate selenium or by creating them manually in your /test/selenium directory. - -## RSelenese, .rsel ## - -RSelenese lets you write your tests in Ruby. This is my favorite format. - - setup :fixtures => :all - open '/' - assert_title 'Home' - ('a'..'z').each {|c| open :controller => 'user', :action => 'create', :name => c } - -See SeleniumOnRails::TestBuilder for available commands. *IMPORTANT NOTE:* RSelenese generates the HTML tables for Selenium behind the scenes when the page is loaded - ONCE. That means code like this: - - (1..10).each do |index| - do something - end - -Will only be executed when the test is loaded, not when the test is run. This is a common error and leads to tests that work the first time and fail the second time. - -## Selenese, .sel ## - -Selenese is the dumbest format (in a good way). You just write your commands delimited by | characters. - - |open|/selenium/setup| - |open|/| - |goBack| - -If you don‘t want to write Selenese tests by hand you can use SeleniumIDE which has support for Selenese. - -## HTML/RHTML ## - -You can write your tests in HTML/RHTML but that‘s mostly useful if you have existing tests you want to reuse. - -## Partial test cases ## - -If you have some common actions you want to do in several test cases you can put them in a separate partial test case and include them in your other test cases. This is highly recommended, just as small functions would be recommended in structured programming. - -A partial test case is just like a normal test case besides that its filename has to start with _: - - #_login.rsel - open '/login' - type 'name', name - type 'password', password - click 'submit', :wait=>true - -To include a partial test case in a RSelenese test case: - - include_partial 'login', :name => 'Jane Doe', :password => 'Jane Doe'.reverse - -in a Selenese test case: - - |includePartial|login|name=John Doe|password=eoD nhoJ| - -and in a RHTML test case: - - <%= render :partial => 'login', :locals => {:name = 'Joe Schmo', :password => 'Joe Schmo'.reverse} %> - -## Configuration ## - -There are a number of settings available. You make them by renaming selenium.yml.example to selenium.yml and placing it in your rails app's config -file. Make your changes in that file. - -## Environments ## - -Per default this plugin is only available in test environment. You can change this by setting environments, such as: - - #selenium.yml - environments: - - test - - development - -## Selenium Core path ## - -If you don‘t want to use the bundled Selenium Core version you can set selenium_path to the directory where Selenium Core is stored. - - #config.yml - selenium_path: 'c:\selenium' - -## Rake Task ## - -You can run all your Selenium tests as a Rake task. If you're using a continuous builder this is a great way to integrate selenium into your build process. First, if you‘re on Windows, you have to make sure win32-open3 is installed. Then you have to configure which browsers you want to run, like this: - - - #config.yml - browsers: - firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe' - ie: 'c:\Program Files\Internet Explorer\iexplore.exe' - -Now you‘re all set. First start a server: - - script/server -e test - -Then run the tests: - - rake test:acceptance - -Now it should work, otherwise let me know! - -## Store results ## - -If you want to store the results from a test:acceptance you just need to set in which directory they should be stored: - - #config.yml - result_dir: 'c:\result' - -So when you run rake test:acceptance the tables with the results will be stored as .html files in that directory. - -## user_extension.js ## - -Selenium has support for user_extension.js which is a way to extend the functionality of Selenium Core. Selenium on Rails now provides the means for you to extend it's functionality to match. - -To get you started, we've included the example files lib/test\_builder\_user\_accessors.rb.example and lib/test\_builder\_user\_actions.rb.example that replicate the sample extensions in Selenium Core's user-extensions.js.sample. - -To get these examples running, simply remove the .example and .sample extensions -from the files and restart your server. - -## Todo ## - -* Standalone mode - More work is needed on test:acceptance< on Windows to be able to start the server when needed. - -* Documentation update - - -## Not todo ## - -* Editor - Creating an editor for the test cases is currently considered out of scope for this plugin. SeleniumIDE[http://www.openqa.org/selenium-ide/] does such a good job and has support[http://wiki.openqa.org/display/SIDE/SeleniumOnRails] for both the Selenese and RSelenese formats. - -## Credits ## - -* Jonas Bengston -- original creator -* Eric Smith, http://blog.8thlight.com/eric -- Current Maintainer -* Jon Tirsen, http://jutopia.tirsen.com -- initial inspiration[http://wiki.rubyonrails.com/rails/pages/SeleniumIntegration] -* Eric Kidd, http://www.randomhacks.net -- contribution of RSelenese -* Marcos Tapajós http://www.improveit.com.br/en/company/tapajos -- Several useful features, current committer -* Ryan Bates, http://railscasts.com -- Fixes for Rails 2.1 -* Nando Vieira, http://simplesideias.com.br -* Gordon McCreight, a neat script that lists any unsupported methods - -## Contributing ## - -Contributing is simple. Fork this repo, make your changes, then issue a pull request. *IMPORTANT* I will not take forks that do not have associated unit tests. There must be tests, and they must pass, so I can bring the changes in. - - -## Information ## - -For more information, check out the [website](http://seleniumhq.org/projects/on-rails/). diff --git a/vendor/plugins/selenium-on-rails/Rakefile b/vendor/plugins/selenium-on-rails/Rakefile deleted file mode 100644 index 60d4c1d1..00000000 --- a/vendor/plugins/selenium-on-rails/Rakefile +++ /dev/null @@ -1,38 +0,0 @@ -require 'rake' -require 'rake/testtask' -require 'rdoc/rdoc' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the Selenium on Rails plugin.' -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.pattern = 'test/**/*_test.rb' - t.verbose = true -end - -desc 'Test the Selenium on Rails plugin, and run the _authortest.rb files, too' -Rake::TestTask.new(:alltests) do |t| - t.libs << 'lib' - # note: Both pattern and test_files are used, so the list of test files is - # the union of the two. - t.pattern = 'test/**/*_test.rb' - t.test_files = FileList['test/**/*_authortest.rb'] - t.verbose = true -end - -desc 'Generate documentation for the Selenium on Rails plugin.' -task :rdoc do - rm_rf 'doc' - RDoc::RDoc.new.document(%w(--line-numbers --inline-source --title SeleniumOnRails README CHANGELOG lib)) -end - -begin - require 'rcov/rcovtask' - Rcov::RcovTask.new do |t| - t.test_files = FileList['test/*_test.rb'] - t.rcov_opts = ['-x /site_ruby/ -x .*gems.* --rails'] - end -rescue LoadError #if rcov isn't available, ignore -end diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumController.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumController.html deleted file mode 100644 index 4df321ba..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumController.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - Class: SeleniumController - - - - - - - - - - -
- - - - - - - - - - - - - - -
ClassSeleniumController
In: - - lib/controllers/selenium_controller.rb - -
-
Parent: - ActionController::Base -
-
- - -
- - - -
- - - -
- -
-

Methods

- -
- record   - setup   - support_file   - test_file   -
-
- -
- - - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/controllers/selenium_controller.rb, line 50
-50:   def record
-51:     dir = record_table
-52: 
-53:     @result = {'resultDir' => dir}
-54:     for p in ['result', 'numTestFailures', 'numTestPasses', 'numCommandFailures', 'numCommandPasses', 'numCommandErrors', 'totalTime']
-55:       @result[p] = params[p]
-56:     end
-57:     File.open(log_path(params[:logFile] || 'default.yml'), 'w') {|f| YAML.dump(@result, f)}
-58:     
-59:     render :file => view_path('record.rhtml'), :layout => layout_path
-60:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/controllers/selenium_controller.rb, line 7
- 7:   def setup
- 8:     unless params.has_key? :keep_session
- 9:       reset_session
-10:       @session_wiped = true
-11:     end
-12:     @cleared_tables = clear_tables params[:clear_tables].to_s
-13:     @loaded_fixtures = load_fixtures params[:fixtures].to_s
-14:     render :file => view_path('setup.rhtml'), :layout => layout_path
-15:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/controllers/selenium_controller.rb, line 34
-34:   def support_file
-35:     if params[:filename].empty?
-36:       redirect_to :filename => 'TestRunner.html', :test => 'tests'
-37:       return
-38:     end
-39: 
-40:     filename = File.join selenium_path, params[:filename]
-41:     if File.file? filename
-42:       type = WEBrick::HTTPUtils::DefaultMimeTypes[$1.downcase] if filename =~ /\.(\w+)$/
-43:       type ||= 'text/html'
-44:       send_file filename, :type => type, :disposition => 'inline', :stream => false
-45:     else
-46:       render :text => 'Not found', :status => 404
-47:     end
-48:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/controllers/selenium_controller.rb, line 17
-17:   def test_file
-18:     params[:testname] = '' if params[:testname].to_s == 'TestSuite.html'
-19:     filename = File.join selenium_tests_path, params[:testname]
-20:     if File.directory? filename
-21:       @suite_path = filename
-22:       render :file => view_path('test_suite.rhtml'), :layout => layout_path
-23:     elsif File.readable? filename
-24:       render_test_case filename
-25:     else
-26:       if File.directory? selenium_tests_path
-27:         render :text => 'Not found', :status => 404
-28:       else
-29:         render :text => "Did not find the Selenium tests path (#{selenium_tests_path}). Run script/generate selenium", :status => 404
-30:       end
-31:     end
-32:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumHelper.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumHelper.html deleted file mode 100644 index ab8fd2c4..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumHelper.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - Module: SeleniumHelper - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumHelper
In: - - lib/selenium_helper.rb - -
-
-
- - -
- - - -
- - - -
- -
-

Methods

- -
- test_case_name   -
-
- -
- - - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_helper.rb, line 5
-5:   def test_case_name filename
-6:     File.basename(filename).sub(/\..*/,'').humanize
-7:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails.html deleted file mode 100644 index ecb45eb3..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - Module: SeleniumOnRails - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails
In: - - lib/selenium_on_rails/paths.rb - -
- - lib/selenium_on_rails.rb - -
-
-
- - -
- - - -
- - - -
- - -
- - - - - - - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/FixtureLoader.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/FixtureLoader.html deleted file mode 100644 index c49a8bbc..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/FixtureLoader.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Module: SeleniumOnRails::FixtureLoader - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::FixtureLoader
In: - - lib/selenium_on_rails/fixture_loader.rb - -
-
-
- - -
- - - -
- - - -
- -
-

Methods

- - -
- -
- - - -
-

Included Modules

- - -
- -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/fixture_loader.rb, line 7
- 7:   def available_fixtures
- 8:     fixtures = {}
- 9:     path = fixtures_path + '/'
-10:     files = Dir["#{path}**/*.{yml,csv}"]
-11:     files.each do |file|
-12:       rel_path = file.sub(path, '')
-13:       next if skip_file? rel_path
-14:       fixture_set = File.dirname(rel_path)
-15:       fixture_set = '' if fixture_set == '.'
-16:       fixture = rel_path.sub /\.[^.]*$/, ''
-17:       fixtures[fixture_set] ||= []
-18:       fixtures[fixture_set] << fixture
-19:     end
-20:     
-21:     fixtures
-22:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/fixture_loader.rb, line 46
-46:   def clear_tables tables
-47:     table_names = tables.split /\s*,\s*/
-48:     connection = ActiveRecord::Base.connection 
-49:     table_names.each do |table|
-50:       connection.execute "DELETE FROM #{table}" 
-51:     end
-52:     table_names
-53:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/fixture_loader.rb, line 24
-24:   def load_fixtures fixtures_param
-25:     available = nil
-26:     fixtures = fixtures_param.split(/\s*,\s*/).collect do |f|
-27:       fixture_set = File.dirname f
-28:       fixture_set = '' if fixture_set == '.'
-29:       fixture = File.basename f
-30:       if fixture == 'all'
-31:         available ||= available_fixtures
-32:         available[fixture_set]
-33:       else
-34:         f
-35:       end
-36:     end
-37:     fixtures.flatten!
-38:     fixtures.reject! {|f| f.blank? }
-39: 
-40:     if fixtures.any?
-41:       Fixtures.create_fixtures fixtures_path, fixtures
-42:     end
-43:     fixtures
-44:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/PartialsSupport.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/PartialsSupport.html deleted file mode 100644 index 0d432d67..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/PartialsSupport.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - Module: SeleniumOnRails::PartialsSupport - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::PartialsSupport
In: - - lib/selenium_on_rails/partials_support.rb - -
-
-
- - -
- - - -
- -
-

-Provides partials support to test cases so they can include other partial -test cases. -

-

-The partial‘s commands are returned as html table rows. -

- -
- - -
- -
-

Methods

- - -
- -
- - - -
-

Included Modules

- - -
- -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

-Extracts the commands from a partial. The partial must contain a html table -and the first row is ignored since it cannot contain a command. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/partials_support.rb, line 19
-19:   def extract_commands_from_partial partial
-20:     partial = partial.match(/.*<table>.*?<tr>.*?<\/tr>(.*?)<\/table>/im)[1]
-21:     raise "Partial '#{name}' doesn't contain any table" unless partial
-22:     partial
-23:   end
-
-
-
-
- -
- - - - -
-

-Overrides where the partial is searched for, and returns only the command -table rows. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/partials_support.rb, line 9
- 9:   def render_partial partial_path = default_template_name, object = nil, local_assigns = nil, status = nil
-10:     pattern = partial_pattern partial_path
-11:     filename = Dir[pattern].first
-12:     raise "Partial '#{partial_path}' cannot be found! (Looking for file: '#{pattern}')" unless filename
-13:     partial = render :file => filename, :use_full_path => false, :locals => local_assigns
-14:     extract_commands_from_partial partial
-15:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Paths.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Paths.html deleted file mode 100644 index 4ee3c542..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Paths.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - Module: SeleniumOnRails::Paths - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::Paths
In: - - lib/selenium_on_rails/paths.rb - -
-
-
- - -
- - - -
- - - -
- -
-

Methods

- - -
- -
- - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 25
-25:     def fixtures_path
-26:       File.expand_path File.join(RAILS_ROOT, 'test/fixtures')
-27:     end
-
-
-
-
- -
- - - - -
-

-Returns the path to the layout template. The path is relative in relation -to the app/views/ directory since Rails doesn‘t support absolute -paths to layout templates. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 19
-19:     def layout_path
-20:       rails_root = Pathname.new File.expand_path(File.join(RAILS_ROOT, 'app/views'))
-21:       view_path = Pathname.new view_path('layout')
-22:       view_path.relative_path_from(rails_root).to_s
-23:     end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 29
-29:     def log_path log_file
-30:       File.expand_path(File.dirname(__FILE__) + '/../../log/' + File.basename(log_file))
-31:     end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_on_rails/paths.rb, line 3
-3:     def selenium_path
-4:       @@selenium_path ||= find_selenium_path
-5:       @@selenium_path
-6:     end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 8
- 8:     def selenium_tests_path
- 9:       File.expand_path(File.join(RAILS_ROOT, 'test/selenium'))
-10:     end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 33
-33:     def skip_file? file
-34:       file.split('/').each do |f|
-35:         return true if f.upcase == 'CVS' or f.starts_with?('.') or f.ends_with?('~') or f.starts_with?('_')
-36:       end
-37:       false
-38:     end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/paths.rb, line 12
-12:     def view_path view
-13:       File.expand_path(File.dirname(__FILE__) + '/../views/' + view)
-14:     end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/RSelenese.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/RSelenese.html deleted file mode 100644 index b57e9c23..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/RSelenese.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - Class: SeleniumOnRails::RSelenese - - - - - - - - - - -
- - - - - - - - - - - - - - -
ClassSeleniumOnRails::RSelenese
In: - - lib/selenium_on_rails/rselenese.rb - -
-
Parent: - - SeleniumOnRails::TestBuilder - -
-
- - -
- - - -
- -
-

-Renders Selenium test templates in a fashion analogous to rxml and -rjs templates. -

-
-  setup
-  open :controller => 'customer', :action => 'list'
-  assert_title 'Customers'
-
-

-See SeleniumOnRails::TestBuilder for a list -of available commands. -

- -
- - -
- -
-

Methods

- -
- new   - render   -
-
- -
- - - - -
- - - - - -
-

Attributes

- -
- - - - - - -
view [RW] 
-
-
- - - - -
-

Public Class methods

- -
- - - - -
-

-Create a new RSelenese renderer bound to view. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/rselenese.rb, line 17
-17:   def initialize view
-18:     super view
-19:     @view = view
-20:   end
-
-
-
-
- -

Public Instance methods

- -
- - - - -
-

-Render template using local_assigns. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/rselenese.rb, line 23
-23:   def render template, local_assigns
-24:     title = (@view.assigns['page_title'] or local_assigns['page_title'])
-25:     table(title) do
-26:       test = self #to enable test.command

-27: 
-28:       assign_locals_code = ''
-29:       local_assigns.each_key {|key| assign_locals_code << "#{key} = local_assigns[#{key.inspect}];"}
-30: 
-31:       eval assign_locals_code + "\n" + template
-32:     end
-33:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Renderer.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Renderer.html deleted file mode 100644 index ca8e1612..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Renderer.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - Module: SeleniumOnRails::Renderer - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::Renderer
In: - - lib/selenium_on_rails/renderer.rb - -
-
-
- - -
- - - -
- - - -
- -
-

Methods

- - -
- -
- - - -
-

Included Modules

- - -
- -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/renderer.rb, line 5
- 5:   def render_test_case filename
- 6:     @template.extend SeleniumOnRails::PartialsSupport
- 7:     @page_title = test_case_name filename
- 8:     output = render_to_string :file => filename
- 9:     layout = (output =~ /<html>/i ? false : layout_path)
-10:     render :text => output, :layout => layout
-11: 
-12:     headers['Cache-control'] = 'no-cache'
-13:     headers['Pragma'] = 'no-cache'
-14:     headers['Expires'] = '-1'
-15:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Selenese.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Selenese.html deleted file mode 100644 index ba3c1648..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Selenese.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - Class: SeleniumOnRails::Selenese - - - - - - - - - - -
- - - - - - - - - - - - - - -
ClassSeleniumOnRails::Selenese
In: - - lib/selenium_on_rails/selenese.rb - -
-
Parent: - Object -
-
- - -
- - - -
- - - -
- -
-

Methods

- -
- new   - render   -
-
- -
- - - - -
- - - - - - - - - -
-

Public Class methods

- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_on_rails/selenese.rb, line 7
-7:   def initialize view
-8:     @view = view
-9:   end
-
-
-
-
- -

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/selenese.rb, line 11
-11:   def render template, local_assigns
-12:     name = (@view.assigns['page_title'] or local_assigns['page_title'])
-13:     lines = template.strip.split "\n"
-14:     html = ''
-15:     html << extract_comments(lines)
-16:     html << extract_commands(lines, name)
-17:     html << extract_comments(lines)
-18:     raise 'You cannot have comments in the middle of commands!' if next_line lines, :any
-19:     html
-20:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/SuiteRenderer.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/SuiteRenderer.html deleted file mode 100644 index a2d00bad..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/SuiteRenderer.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - Module: SeleniumOnRails::SuiteRenderer - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::SuiteRenderer
In: - - lib/selenium_on_rails/suite_renderer.rb - -
-
-
- - -
- - - -
- - - -
- -
-

Methods

- - -
- -
- - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/suite_renderer.rb, line 24
-24:   def link_to_test_case suite_name, filename
-25:     name = suite_name + test_case_name(filename)
-26:     link_to name, :action => :test_file, :testname => path_to_relative_url(filename).sub(/^\//,'')
-27:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/suite_renderer.rb, line 18
-18:   def test_cases path
-19:     tests = []
-20:     visit_all_tests path, '', nil, Proc.new {|n, p| tests << [n,p]}
-21:     tests
-22:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_on_rails/suite_renderer.rb, line 2
-2:   def test_suite_name path
-3:     return 'All test cases' if [nil, '/'].include? path_to_relative_url(path)
-4:     File.split(path)[-1].humanize
-5:   end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails/suite_renderer.rb, line 7
- 7:   def test_suites path
- 8:     suites = []
- 9: 
-10:     parent_path = File.join(File.split(path).slice(0..-2)) #all but last

-11:     parent_path = path_to_relative_url parent_path
-12:     suites << ['..', parent_path] unless parent_path.nil?
-13: 
-14:     visit_all_tests path, '', Proc.new {|n, p| suites << [n,path_to_relative_url(p)]}, nil
-15:     suites
-16:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilder.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilder.html deleted file mode 100644 index 7f2aeb6e..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilder.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - Class: SeleniumOnRails::TestBuilder - - - - - - - - - - -
- - - - - - - - - - - - - - -
ClassSeleniumOnRails::TestBuilder
In: - - lib/selenium_on_rails/test_builder.rb - -
-
Parent: - Object -
-
- - -
- - - -
- -
-

-Builds Selenium test table using a -high-level Ruby interface. Normally invoked through SeleniumOnRails::RSelenese. -

-

-See SeleniumOnRails::TestBuilderActions for -the available actions and SeleniumOnRails::TestBuilderAccessors -for the available checks. -

-

-For more information on the commands supported by TestBuilder, see the Selenium Commands -Documentation at release.openqa.org/selenium-core/nightly/reference.html. -

- -
- - -
- -
-

Methods

- -
- collection_arg   - command   - command_and_wait   - command_verbatim   - exactize   - make_command_waiting   - new   - selenize   - table   - url_arg   -
-
- -
- - - - - -
- - - - - - - - - -
-

Public Class methods

- -
- - - - -
-

-Create a new TestBuilder for view. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 47
-47:   def initialize view
-48:     @view = view
-49:     @output = ''
-50:     @xml = Builder::XmlMarkup.new :indent => 2, :target => @output
-51:   end
-
-
-
-
- -
- - - - -
-

-Convert str to a Selenium command name. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 36
-36:   def self.selenize str
-37:     str.camelize.gsub(/^[A-Z]/) {|s| s.downcase }
-38:   end
-
-
-
-
- -

Public Instance methods

- -
- - - - -
-

-Add a new test command using cmd, -target and value. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 62
-62:   def command cmd, target=nil, value=nil
-63:     @xml.tr do
-64:       _tdata cmd
-65:       _tdata target
-66:       _tdata value
-67:     end
-68:   end
-
-
-
-
- -
- - - - -
-

-Same as command but add -AndWait to the name of cmd. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 73
-73:   def command_and_wait cmd, target=nil, value=nil
-74:     command_verbatim cmd.to_s + 'AndWait', target, value
-75:   end
-
-
-
-
- -
- - -
- command_verbatim(cmd, target=nil, value=nil) -
- -
-

-Alias for command -

-
-
- -
- - - - -
-

-Prepends pattern with ‘exact:’ if it would be -considered containing string-match pattern otherwise. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 42
-42:   def exactize pattern
-43:     pattern.include?(':') ? "exact:#{pattern}" : pattern
-44:   end
-
-
-
-
- -
- - - - -
-

-Re routes commands in the provided block to command_and_wait instead of command. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 79
-79:   def make_command_waiting
-80:     self.class.send :alias_method, :command, :command_and_wait
-81:     yield
-82:     self.class.send :alias_method, :command, :command_verbatim 
-83:   end
-
-
-
-
- -
- - - - -
-

-Add a new table of tests, and return the HTML. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 54
-54:   def table title
-55:     @xml.table do
-56:       @xml.tr do @xml.th(title, :colspan => 3) end
-57:       yield self
-58:     end
-59:   end
-
-
-
-
- -

Protected Instance methods

- -
- - - - -
-

-If arg is an array formats arg to a textual -representation. Otherwise return unchanged. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder.rb, line 95
- 95:   def collection_arg arg
- 96:     if arg.is_a? Array
- 97:       arg.collect {|e| e.gsub(/[\\,]/) {|s| "\\#{s}" } }.join(',')
- 98:     else
- 99:       arg
-100:     end
-101:   end
-
-
-
-
- -
- - - - -
-

-If url is a string, return unchanged. Otherwise, pass it to -ActionView#UrlHelper#url_for. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder.rb, line 89
-89:   def url_arg url
-90:     if url.instance_of?(String) then url else exactize(@view.url_for(url)) end
-91:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderAccessors.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderAccessors.html deleted file mode 100644 index 16c6c020..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderAccessors.html +++ /dev/null @@ -1,3098 +0,0 @@ - - - - - - Module: SeleniumOnRails::TestBuilderAccessors - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::TestBuilderAccessors
In: - - lib/selenium_on_rails/test_builder_accessors.rb - -
-
-
- - -
- - - -
- -
-

-The accessors available for SeleniumOnRails::TestBuilder tests. -

-

-For each store_foo there‘s assert_foo, -assert_not_foo, verify_foo, verify_not_foo, -wait_for_foo, wait_for_not_foo. -

- -
- - -
- - - -
- - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

-Gets the absolute URL of the current page. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_absolute_location(pattern) - -
  • -
  • assert_not_absolute_location(pattern) - -
  • -
  • verify_absolute_location_present(pattern) - -
  • -
  • verify_not_absolute_location(pattern) - -
  • -
  • wait_for_absolute_location(pattern) - -
  • -
  • wait_for_not_absolute_location(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 246
-246:   def store_absolute_location variable_name
-247:     command 'storeAbsoluteLocation', variable_name
-248:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the message of a JavaScript alert generated during the previous -action, or fail if there were no alerts. -

-

-Getting an alert has the same effect as manually clicking OK. If an alert -is generated but you do not get/verify it, the next Selenium action will -fail. -

-

-NOTE: under Selenium, JavaScript alerts will NOT pop up a visible alert -dialog. -

-

-NOTE: Selenium does NOT support JavaScript alerts that are generated in a -page‘s onload() event handler. In this case a visible dialog -WILL be generated and Selenium will hang until someone manually clicks OK. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_alert(pattern) - -
  • -
  • assert_not_alert(pattern) - -
  • -
  • verify_alert_present(pattern) - -
  • -
  • verify_not_alert(pattern) - -
  • -
  • wait_for_alert(pattern) - -
  • -
  • wait_for_not_alert(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 183
-183:   def store_alert variable_name
-184:     command 'storeAlert', variable_name
-185:   end
-
-
-
-
- -
- - - - -
-

-Has an alert occurred? -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_alert_present - -
  • -
  • assert_alert_not_present - -
  • -
  • verify_alert_present - -
  • -
  • verify_alert_not_present - -
  • -
  • wait_for_alert_present - -
  • -
  • wait_for_alert_not_present - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 89
-89:   def store_alert_present variable_name
-90:     command 'storeAlertPresent', variable_name
-91:   end
-
-
-
-
- -
- - - - -
-

-Returns the IDs of all buttons on the page. -

-

-If a given button has no ID, it will appear as "" in this array. -

-

-The pattern for the automatically generated assertions can either -take an array or a pattern. -

-
- assert_all_buttons ['but1', 'but2']
- assert_all_buttons 'but?,but?*'
-
-

-Related Assertions, automatically generated: -

-
    -
  • assert_all_buttons(pattern) - -
  • -
  • assert_not_all_buttons(pattern) - -
  • -
  • verify_all_buttons(pattern) - -
  • -
  • verify_not_all_buttons(pattern) - -
  • -
  • wait_for_all_buttons(pattern) - -
  • -
  • wait_for_not_all_buttons(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 754
-754:   def store_all_buttons variable_name
-755:     command 'storeAllButtons', variable_name
-756:   end
-
-
-
-
- -
- - - - -
-

-Returns the IDs of all input fields on the page. -

-

-If a given field has no ID, it will appear as "" in this array. -

-

-The pattern for the automatically generated assertions can either -take an array or a pattern. -

-
- assert_all_fields ['field1', 'field2']
- assert_all_fields 'field?,field?*'
-
-

-Related Assertions, automatically generated: -

-
    -
  • assert_all_fields(pattern) - -
  • -
  • assert_not_all_fields(pattern) - -
  • -
  • verify_all_fields(pattern) - -
  • -
  • verify_not_all_fields(pattern) - -
  • -
  • wait_for_all_fields(pattern) - -
  • -
  • wait_for_not_all_fields(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 794
-794:   def store_all_fields variable_name
-795:     command 'storeAllFields', variable_name
-796:   end
-
-
-
-
- -
- - - - -
-

-Returns the IDs of all links on the page. -

-

-If a given link has no ID, it will appear as "" in this array. -

-

-The pattern for the automatically generated assertions can either -take an array or a pattern. -

-
- assert_all_links ['link1', 'link2']
- assert_all_links 'link?,link?*'
-
-

-Related Assertions, automatically generated: -

-
    -
  • assert_all_links(pattern) - -
  • -
  • assert_not_all_links(pattern) - -
  • -
  • verify_all_links(pattern) - -
  • -
  • verify_not_all_links(pattern) - -
  • -
  • wait_for_all_links(pattern) - -
  • -
  • wait_for_not_all_links(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 774
-774:   def store_all_links variable_name
-775:     command 'storeAllLinks', variable_name
-776:   end
-
-
-
-
- -
- - - - -
-

-Returns the IDs of all windows that the browser knows about. -

-

-Related Assertions, automatically generated: -

-
    -
  • assertAllWindowIds(pattern) - -
  • -
  • assertNotAllWindowIds(pattern) - -
  • -
  • verifyAllWindowIds(pattern) - -
  • -
  • verifyNotAllWindowIds(pattern) - -
  • -
  • waitForAllWindowIds(pattern) - -
  • -
  • waitForNotAllWindowIds(pattern) - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 50
-50:   def store_all_window_ids variable_name
-51:     command 'storeAllWindowIds', variable_name
-52:   end
-
-
-
-
- -
- - - - -
-

-Returns the names of all windows that the browser knows about. -

-

-Related Assertions, automatically generated: -

-
    -
  • assertAllWindowNames(pattern) - -
  • -
  • assertNotAllWindowNames(pattern) - -
  • -
  • verifyAllWindowNames(pattern) - -
  • -
  • verifyNotAllWindowNames(pattern) - -
  • -
  • waitForAllWindowNames(pattern) - -
  • -
  • waitForNotAllWindowNames(pattern) - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 63
-63:   def store_all_window_names variable_name
-64:     command 'storeAllWindowNames', variable_name
-65:   end
-
-
-
-
- -
- - - - -
-

-Returns the titles of all windows that the browser knows about. -

-

-Related Assertions, automatically generated: -

-
    -
  • assertAllWindowTitles(pattern) - -
  • -
  • assertNotAllWindowTitles(pattern) - -
  • -
  • verifyAllWindowTitles(pattern) - -
  • -
  • verifyNotAllWindowTitles(pattern) - -
  • -
  • waitForAllWindowTitles(pattern) - -
  • -
  • waitForNotAllWindowTitles(pattern) - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 76
-76:   def store_all_window_titles variable_name
-77:     command 'storeAllWindowTitles', variable_name
-78:   end
-
-
-
-
- -
- - - - -
-

-Gets the value of an element attribute. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_attribute(locator, attribute_name, pattern) - -
  • -
  • assert_not_attribute(locator, attribute_name, pattern) - -
  • -
  • verify_attribute_present(locator, attribute_name, pattern) - -
  • -
  • verify_not_attribute(locator, attribute_name, pattern) - -
  • -
  • wait_for_attribute(locator, attribute_name, pattern) - -
  • -
  • wait_for_not_attribute(locator, attribute_name, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 577
-577:   def store_attribute locator, attribute_name, variable_name
-578:     command 'storeAttribute', "#{locator}@#{attribute_name}", variable_name
-579:   end
-
-
-
-
- -
- - - - -
-

-Returns every instance of some attribute from all known windows. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_attribute_from_all_windows(attribute_name, pattern) - -
  • -
  • assert_not_attribute_from_all_windows(attribute_name, pattern) - -
  • -
  • verify_attribute_from_all_windows(attribute_name, pattern) - -
  • -
  • verify_not_attribute_from_all_windows(attribute_name, pattern) - -
  • -
  • wait_for_attribute_from_all_windows(attribute_name, pattern) - -
  • -
  • wait_for_not_attribute_from_all_windows(attribute_name, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 102
-102:   def store_attribute_from_all_windows attribute_name, variable_name
-103:     command 'storeAttributeFromAllWindows', attribute_name, variable_name
-104:   end
-
-
-
-
- -
- - - - -
-

-Gets the entire text of the page. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_body_text(pattern) - -
  • -
  • assert_not_body_text(pattern) - -
  • -
  • verify_body_text_present(pattern) - -
  • -
  • verify_not_body_text(pattern) - -
  • -
  • wait_for_body_text(pattern) - -
  • -
  • wait_for_not_body_text(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 300
-300:   def store_body_text variable_name
-301:     command 'storeBodyText', variable_name
-302:   end
-
-
-
-
- -
- - - - -
-

-Gets whether a toggle-button (checkbox/radio) is checked. Fails if the -specified element doesn‘t exist or isn‘t a toggle-button. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_checked(locator) - -
  • -
  • assert_not_checked(locator) - -
  • -
  • verify_checked_present(locator) - -
  • -
  • verify_not_checked(locator) - -
  • -
  • wait_for_checked(locator) - -
  • -
  • wait_for_not_checked(locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 370
-370:   def store_checked locator, variable_name
-371:     command 'storeChecked', locator, variable_name
-372:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the message of a JavaScript confirmation dialog generated during -the previous action. -

-

-By default, the confirm function will return true, having the same -effect as manually clicking OK. This can be changed by prior execution of -the choose_cancel_on_next_confirmation command. If a confirmation -is generated but you do not get/verify it, the next Selenium action will -fail. -

-

-NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible -dialog. -

-

-NOTE: Selenium does NOT support JavaScript confirmations that are generated -in a page‘s onload() event handler. In this case a visible -dialog WILL be generated and Selenium will hang until you manually click -OK. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_confirmation(pattern) - -
  • -
  • assert_not_confirmation(pattern) - -
  • -
  • verify_confirmation_present(pattern) - -
  • -
  • verify_not_confirmation(pattern) - -
  • -
  • wait_for_confirmation(pattern) - -
  • -
  • wait_for_not_confirmation(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 209
-209:   def store_confirmation variable_name
-210:     command 'storeConfirmation', variable_name
-211:   end
-
-
-
-
- -
- - - - -
-

-Has confirm() been called? -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_confirmation_present - -
  • -
  • assert_confirmation_not_present - -
  • -
  • verify_confirmation_present - -
  • -
  • verify_confirmation_not_present - -
  • -
  • wait_for_confirmation_present - -
  • -
  • wait_for_confirmation_not_present - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 128
-128:   def store_confirmation_present variable_name
-129:     command 'storeConfirmationPresent', variable_name
-130:   end
-
-
-
-
- -
- - - - -
-

-Return all cookies of the current page under test. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_cookie(pattern) - -
  • -
  • assert_not_cookie(pattern) - -
  • -
  • verify_cookie(pattern) - -
  • -
  • verify_not_cookie(pattern) - -
  • -
  • wait_for_cookie(pattern) - -
  • -
  • wait_for_not_cookie(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 141
-141:   def store_cookie variable_name
-142:     command 'storeCookie', variable_name
-143:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the text cursor position in the given input element or textarea; -beware, this may not work perfectly on all browsers. -

-

-This method will fail if the specified element isn‘t an input element -or textarea, or there is no cursor in the element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_cursor_position(locator, pattern) - -
  • -
  • assert_not_cursor_position(locator, pattern) - -
  • -
  • verify_cursor_position(locator, pattern) - -
  • -
  • verify_not_cursor_position(locator, pattern) - -
  • -
  • wait_for_cursor_position(locator, pattern) - -
  • -
  • wait_for_not_cursor_position(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 158
-158:   def store_cursor_position locator, variable_name
-159:     command 'storeCursorPosition', locator, variable_name
-160:   end
-
-
-
-
- -
- - - - -
-

-Determines whether the specified input element is editable, i.e. -hasn‘t been disabled. This method will fail if the specified element -isn‘t an input element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_editable(locator) - -
  • -
  • assert_not_editable(locator) - -
  • -
  • verify_editable(locator) - -
  • -
  • verify_not_editable(locator) - -
  • -
  • wait_for_editable(locator) - -
  • -
  • wait_for_not_editable(locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 734
-734:   def store_editable locator, variable_name
-735:     command 'storeEditable', locator, variable_name
-736:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the height of an element. This method will fail if the element is -not present. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_height(locator, pattern) - -
  • -
  • assert_not_element_height(locator, pattern) - -
  • -
  • verify_element_height(locator, pattern) - -
  • -
  • verify_not_element_height(locator, pattern) - -
  • -
  • wait_for_element_height(locator, pattern) - -
  • -
  • wait_for_not_element_height(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 650
-650:   def store_element_height locator, variable_name
-651:     command 'storeElementHeight', locator, variable_name
-652:   end
-
-
-
-
- -
- - - - -
-

-Get the relative index of an element to its parent (starting from 0). The -comment node and empty text node will be ignored. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_index(locator, pattern) - -
  • -
  • assert_not_element_index(locator, pattern) - -
  • -
  • verify_element_index(locator, pattern) - -
  • -
  • verify_not_element_index(locator, pattern) - -
  • -
  • wait_for_element_index(locator, pattern) - -
  • -
  • wait_for_not_element_index(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 664
-664:   def store_element_index locator, variable_name
-665:     command 'storeElementIndex', locator, variable_name
-666:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the horizontal position of an element. This method will fail if -the element is not present. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_position_left(locator, pattern) - -
  • -
  • assert_not_element_position_left(locator, pattern) - -
  • -
  • verify_element_position_left(locator, pattern) - -
  • -
  • verify_not_element_position_left(locator, pattern) - -
  • -
  • wait_for_element_position_left(locator, pattern) - -
  • -
  • wait_for_not_element_position_left(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 692
-692:   def store_element_position_left locator, variable_name
-693:     command 'storeElementPositionLeft', locator, variable_name
-694:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the vertical position of an element. This method will fail if the -element is not present. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_position_top(locator, pattern) - -
  • -
  • assert_not_element_position_top(locator, pattern) - -
  • -
  • verify_element_position_top(locator, pattern) - -
  • -
  • verify_not_element_position_top(locator, pattern) - -
  • -
  • wait_for_element_position_top(locator, pattern) - -
  • -
  • wait_for_not_element_position_top(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 706
-706:   def store_element_position_top locator, variable_name
-707:     command 'storeElementPositionTop', locator, variable_name
-708:   end
-
-
-
-
- -
- - - - -
-

-Verifies that the specified element is somewhere on the page. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_present(locator) - -
  • -
  • assert_element_not_present(locator) - -
  • -
  • verify_element_present(locator) - -
  • -
  • verify_element_not_present(locator) - -
  • -
  • wait_for_element_present(locator) - -
  • -
  • wait_for_element_not_present(locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 620
-620:   def store_element_present locator, variable_name
-621:     command 'storeElementPresent', locator, variable_name
-622:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the width of an element. This method will fail if the element is -not present. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_element_width(locator, pattern) - -
  • -
  • assert_not_element_width(locator, pattern) - -
  • -
  • verify_element_width(locator, pattern) - -
  • -
  • verify_not_element_width(locator, pattern) - -
  • -
  • wait_for_element_width(locator, pattern) - -
  • -
  • wait_for_not_element_width(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 678
-678:   def store_element_width locator, variable_name
-679:     command 'storeElementWidth', locator, variable_name
-680:   end
-
-
-
-
- -
- - - - -
-

-Tell Selenium to expect an error on the next command execution. -

-

-NOTE: store_error_on_next is -currently not supported by Selenium Core and is only added to here as a -shortcut for generating the related assertions. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_error_on_next(message) - -
  • -
  • assert_not_error_on_next(message) - -
  • -
  • verify_error_on_next(message) - -
  • -
  • verify_not_error_on_next(message) - -
  • -
  • wait_for_error_on_next(message) - -
  • -
  • wait_for_not_error_on_next(message) - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 20
-20:   def store_error_on_next message
-21:     raise 'Not supported in Selenium Core at the moment'
-22:   end
-
-
-
-
- -
- - - - -
-

-Gets the result of evaluating the specified JavaScript snippet. The snippet -may have multiple lines, but only the result of the last line will be -returned. -

-

-Note that, by default, the snippet will run in the context of the -"selenium" object itself, so this will refer to the -Selenium object, and window will refer to the top-level runner -test window, not the window of your application. -

-

-If you need a reference to the window of your application, you can refer to -this.browserbot.getCurrentWindow() and if you need to use a -locator to refer to a single element in your application page, you can use -this.page().findElement("foo") where -"foo" is your locator. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_eval(script, pattern) - -
  • -
  • assert_not_eval(script, pattern) - -
  • -
  • verify_eval_present(script, pattern) - -
  • -
  • verify_not_eval(script, pattern) - -
  • -
  • wait_for_eval(script, pattern) - -
  • -
  • wait_for_not_eval(script, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 356
-356:   def store_eval script, variable_name
-357:     command 'storeEval', script, variable_name
-358:   end
-
-
-
-
- -
- - - - -
-

-Returns the specified expression. -

-

-This is useful because of JavaScript preprocessing. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_expression(expression, pattern) - -
  • -
  • assert_not_expression(expression, pattern) - -
  • -
  • verify_expression(expression, pattern) - -
  • -
  • verify_not_expression(expression, pattern) - -
  • -
  • wait_for_expression(expression, pattern) - -
  • -
  • wait_for_not_expression(expression, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 822
-822:   def store_expression expression, variable_name
-823:     command 'storeExpression', expression, variable_name
-824:   end
-
-
-
-
- -
- - - - -
-

-Tell Selenium to expect a failure on the next command execution. -

-

-NOTE: store_failure_on_next is -currently not supported by Selenium Core and is only added to here as a -shortcut for generating the related assertions. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_failure_on_next(message) - -
  • -
  • assert_not_failure_on_next(message) - -
  • -
  • verify_failure_on_next(message) - -
  • -
  • verify_not_failure_on_next(message) - -
  • -
  • wait_for_failure_on_next(message) - -
  • -
  • wait_for_not_failure_on_next(message) - -
  • -
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_accessors.rb, line 37
-37:   def store_failure_on_next message
-38:     raise 'Not supported in Selenium Core at the moment'
-39:   end
-
-
-
-
- -
- - - - -
-

-Returns the entire HTML source between the opening and closing -"html" tags. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_html_source(pattern) - -
  • -
  • assert_not_html_source(pattern) - -
  • -
  • verify_html_source(pattern) - -
  • -
  • verify_not_html_source(pattern) - -
  • -
  • wait_for_html_source(pattern) - -
  • -
  • wait_for_not_html_source(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 807
-807:   def store_html_source variable_name
-808:     command 'storeHtmlSource', variable_name
-809:   end
-
-
-
-
- -
- - - - -
-

-Verify the location of the current page ends with the expected location. If -an URL querystring is provided, this is checked as well. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_location(pattern) - -
  • -
  • assert_not_location(pattern) - -
  • -
  • verify_location_present(pattern) - -
  • -
  • verify_not_location(pattern) - -
  • -
  • wait_for_location(pattern) - -
  • -
  • wait_for_not_location(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 260
-260:   def store_location expected_location, variable_name
-261:     command 'storeLocation', expected_location, variable_name
-262:   end
-
-
-
-
- -
- - - - -
-

-Return the contents of the log. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_log_messages(pattern) - -
  • -
  • assert_not_log_messages(pattern) - -
  • -
  • verify_log_messages(pattern) - -
  • -
  • verify_not_log_messages(pattern) - -
  • -
  • wait_for_log_messages(pattern) - -
  • -
  • wait_for_not_log_messages(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 719
-719:   def store_log_messages variable_name
-720:     command 'storeLogMessages', variable_name
-721:   end
-
-
-
-
- -
- - - - -
-

-Returns the number of pixels between "mousemove" events during -drag_and_drop commands (default=10). -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_mouse_speed(pattern) - -
  • -
  • assert_not_mouse_speed(pattern) - -
  • -
  • verify_mouse_speed(pattern) - -
  • -
  • verify_not_mouse_speed(pattern) - -
  • -
  • wait_for_mouse_speed(pattern) - -
  • -
  • wait_for_not_mouse_speed(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 274
-274:   def store_mouse_speed variable_name
-275:     command 'storeMouseSpeed', variable_name
-276:   end
-
-
-
-
- -
- - - - -
-

-Check if these two elements have same parent and are ordered. Two same -elements will not be considered ordered. -

-

-NOTE: store_ordered is -currently not supported by Selenium Core. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_ordered(locator_1, locator_2) - -
  • -
  • assert_not_ordered(locator_1, locator_2) - -
  • -
  • verify_ordered(locator_1, locator_2) - -
  • -
  • verify_not_ordered(locator_1, locator_2) - -
  • -
  • wait_for_ordered(locator_1, locator_2) - -
  • -
  • wait_for_not_ordered(locator_1, locator_2) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 593
-593:   def store_ordered locator_1, locator_2, variable_name
-594:     raise 'Not supported in Selenium Core at the moment'
-595:   end
-
-
-
-
- -
- - - - -
-

-Retrieves the message of a JavaScript question prompt dialog generated -during the previous action. -

-

-Successful handling of the prompt requires prior execution of the -answer_on_next_prompt command. If a prompt is generated but you do -not get/verify it, the next Selenium action will fail. -

-

-NOTE: under Selenium, JavaScript prompts will NOT pop up a visible dialog. -

-

-NOTE: Selenium does NOT support JavaScript prompts that are generated in a -page‘s onload() event handler. In this case a visible dialog -WILL be generated and Selenium will hang until someone manually clicks OK. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_prompt(pattern) - -
  • -
  • assert_not_prompt(pattern) - -
  • -
  • verify_prompt_present(pattern) - -
  • -
  • verify_not_prompt(pattern) - -
  • -
  • wait_for_prompt(pattern) - -
  • -
  • wait_for_not_prompt(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 233
-233:   def store_prompt variable_name
-234:     command 'storePrompt', variable_name
-235:   end
-
-
-
-
- -
- - - - -
-

-Has a prompt occurred? -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_prompt_present - -
  • -
  • assert_prompt_not_present - -
  • -
  • verify_prompt_present - -
  • -
  • verify_prompt_not_present - -
  • -
  • wait_for_prompt_present - -
  • -
  • wait_for_prompt_not_present - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 115
-115:   def store_prompt_present variable_name
-116:     command 'storePromptPresent', variable_name
-117:   end
-
-
-
-
- -
- - - - -
-

-Gets all option labels in the specified select drop-down. -

-

-The pattern for the automatically generated assertions can either -take an array or a pattern. -

-
- assert_select_options 'fruits', ['apple', 'pear']
- assert_select_options 'fruits', 'a*,p*'
-
-

-Related Assertions, automatically generated: -

-
    -
  • assert_select_options(locator, pattern) - -
  • -
  • assert_not_select_options(locator, pattern) - -
  • -
  • verify_select_options_present(locator, pattern) - -
  • -
  • verify_not_select_options(locator, pattern) - -
  • -
  • wait_for_select_options(locator, pattern) - -
  • -
  • wait_for_not_select_options(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 564
-564:   def store_select_options locator, variable_name
-565:     command 'storeSelectOptions', locator, variable_name
-566:   end
-
-
-
-
- -
- - - - -
-

-Verifies that the selected option of a drop-down satisfies the -option_locator. -

-

-option_locator is typically just an option label (e.g. "John -Smith"). -

-

-See the select command for more information about option locators. -

-

-NOTE: store_selected is -currently not supported by Selenium Core. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected(locator, option_locator) - -
  • -
  • assert_not_selected(locator, option_locator) - -
  • -
  • verify_selected_present(locator, option_locator) - -
  • -
  • verify_not_selected(locator, option_locator) - -
  • -
  • wait_for_selected(locator, option_locator) - -
  • -
  • wait_for_not_selected(locator, option_locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 403
-403:   def store_selected locator, option_locator, variable_name
-404:     raise 'Not supported in Selenium Core at the moment'
-405:   end
-
-
-
-
- -
- - - - -
-

-Gets option element ID for selected option in the specified select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_id(select_locator, pattern) - -
  • -
  • assert_not_selected_id(select_locator, pattern) - -
  • -
  • verify_selected_id(select_locator, pattern) - -
  • -
  • verify_not_selected_id(select_locator, pattern) - -
  • -
  • wait_for_selected_id(select_locator, pattern) - -
  • -
  • wait_for_not_selected_id(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 416
-416:   def store_selected_id select_locator, variable_name
-417:     command 'storeSelectedId', select_locator, variable_name
-418:   end
-
-
-
-
- -
- - - - -
-

-Gets all option element IDs for selected options in the specified select or -multi-select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_ids(select_locator, pattern) - -
  • -
  • assert_not_selected_ids(select_locator, pattern) - -
  • -
  • verify_selected_ids(select_locator, pattern) - -
  • -
  • verify_not_selected_ids(select_locator, pattern) - -
  • -
  • wait_for_selected_ids(select_locator, pattern) - -
  • -
  • wait_for_not_selected_ids(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 430
-430:   def store_selected_ids select_locator, variable_name
-431:     command 'storeSelectedIds', select_locator, variable_name
-432:   end
-
-
-
-
- -
- - - - -
-

-Gets option index (option number, starting at 0) for selected option in the -specified select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_index(select_locator, pattern) - -
  • -
  • assert_not_selected_index(select_locator, pattern) - -
  • -
  • verify_selected_index(select_locator, pattern) - -
  • -
  • verify_not_selected_index(select_locator, pattern) - -
  • -
  • wait_for_selected_index(select_locator, pattern) - -
  • -
  • wait_for_not_selected_index(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 444
-444:   def store_selected_index select_locator, variable_name
-445:     command 'storeSelectedIndex', select_locator, variable_name
-446:   end
-
-
-
-
- -
- - - - -
-

-Gets all option indexes (option number, starting at 0) for selected options -in the specified select or multi-select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_indexes(select_locator, pattern) - -
  • -
  • assert_not_selected_indexes(select_locator, pattern) - -
  • -
  • verify_selected_indexes(select_locator, pattern) - -
  • -
  • verify_not_selected_indexes(select_locator, pattern) - -
  • -
  • wait_for_selected_indexes(select_locator, pattern) - -
  • -
  • wait_for_not_selected_indexes(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 458
-458:   def store_selected_indexes select_locator, variable_name
-459:     command 'storeSelectedIndexes', select_locator, variable_name
-460:   end
-
-
-
-
- -
- - - - -
-

-Gets option label (visible text) for selected option in the specified -select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_label(select_locator, pattern) - -
  • -
  • assert_not_selected_label(select_locator, pattern) - -
  • -
  • verify_selected_label(select_locator, pattern) - -
  • -
  • verify_not_selected_label(select_locator, pattern) - -
  • -
  • wait_for_selected_label(select_locator, pattern) - -
  • -
  • wait_for_not_selected_label(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 472
-472:   def store_selected_label select_locator, variable_name
-473:     command 'storeSelectedLabel', select_locator, variable_name
-474:   end
-
-
-
-
- -
- - - - -
-

-Gets all option labels (visible text) for selected options in the specified -select or multi-select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_labels(select_locator, pattern) - -
  • -
  • assert_not_selected_labels(select_locator, pattern) - -
  • -
  • verify_selected_labels(select_locator, pattern) - -
  • -
  • verify_not_selected_labels(select_locator, pattern) - -
  • -
  • wait_for_selected_labels(select_locator, pattern) - -
  • -
  • wait_for_not_selected_labels(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 486
-486:   def store_selected_labels select_locator, variable_name
-487:     command 'storeSelectedLabels', select_locator, variable_name
-488:   end
-
-
-
-
- -
- - - - -
-

-Gets all option labels for selected options in the specified select or -multi-select element. -

-

-The pattern for the automatically generated assertions can either -take an array or a pattern. -

-
- assert_selected_options 'fruits', ['apple', 'pear']
- assert_selected_options 'fruits', 'a*,p*'
-
-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_options(locator, pattern) - -
  • -
  • assert_not_selected_options(locator, pattern) - -
  • -
  • verify_selected_options_present(locator, pattern) - -
  • -
  • verify_not_selected_options(locator, pattern) - -
  • -
  • wait_for_selected_options(locator, pattern) - -
  • -
  • wait_for_not_selected_options(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 546
-546:   def store_selected_options locator, variable_name
-547:     command 'storeSelectedOptions', locator, variable_name
-548:   end
-
-
-
-
- -
- - - - -
-

-Gets option value (value attribute) for selected option in the specified -select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_value(select_locator, pattern) - -
  • -
  • assert_not_selected_value(select_locator, pattern) - -
  • -
  • verify_selected_value(select_locator, pattern) - -
  • -
  • verify_not_selected_value(select_locator, pattern) - -
  • -
  • wait_for_selected_value(select_locator, pattern) - -
  • -
  • wait_for_not_selected_value(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 500
-500:   def store_selected_value select_locator, variable_name
-501:     command 'storeSelectedValue', select_locator, variable_name
-502:   end
-
-
-
-
- -
- - - - -
-

-Gets all option values (value attribute) for selected options in the -specified select or multi-select element. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_selected_values(select_locator, pattern) - -
  • -
  • assert_not_selected_values(select_locator, pattern) - -
  • -
  • verify_selected_values(select_locator, pattern) - -
  • -
  • verify_not_selected_values(select_locator, pattern) - -
  • -
  • wait_for_selected_values(select_locator, pattern) - -
  • -
  • wait_for_not_selected_values(select_locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 514
-514:   def store_selected_values select_locator, variable_name
-515:     command 'storeSelectedValues', select_locator, variable_name
-516:   end
-
-
-
-
- -
- - - - -
-

-Determines whether some option in a drop-down menu is selected. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_something_selected(select_locator) - -
  • -
  • assert_not_something_selected(select_locator) - -
  • -
  • verify_something_selected(select_locator) - -
  • -
  • verify_not_something_selected(select_locator) - -
  • -
  • wait_for_something_selected(select_locator) - -
  • -
  • wait_for_not_something_selected(select_locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 527
-527:   def store_something_selected select_locator, variable_name
-528:     command 'storeSomethingSelected', select_locator, variable_name
-529:   end
-
-
-
-
- -
- - - - -
-

-Gets the text from a cell of a table. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_table(locator, row, column, pattern) - -
  • -
  • assert_not_table(locator, row, column, pattern) - -
  • -
  • verify_table_present(locator, row, column, pattern) - -
  • -
  • verify_not_table(locator, row, column, pattern) - -
  • -
  • wait_for_table(locator, row, column, pattern) - -
  • -
  • wait_for_not_table(locator, row, column, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 383
-383:   def store_table locator, row, column, variable_name
-384:     command 'storeTable', "#{locator}.#{row}.#{column}", variable_name
-385:   end
-
-
-
-
- -
- - - - -
-

-Gets the text of an element. This works for any element that contains text. -This command uses either the textContent (Mozilla-like browsers) -or the innerText (IE-like browsers) of the element, which is the -rendered text shown to the user. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_text(locator, pattern) - -
  • -
  • assert_not_text(locator, pattern) - -
  • -
  • verify_text_present(locator, pattern) - -
  • -
  • verify_not_text(locator, pattern) - -
  • -
  • wait_for_text(locator, pattern) - -
  • -
  • wait_for_not_text(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 331
-331:   def store_text locator, variable_name
-332:     command 'storeText', locator, variable_name
-333:   end
-
-
-
-
- -
- - - - -
-

-Verifies that the specified text pattern appears somewhere on the rendered -page shown to the user. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_text_present(pattern) - -
  • -
  • assert_text_not_present(pattern) - -
  • -
  • verify_text_present(pattern) - -
  • -
  • verify_text_not_present(pattern) - -
  • -
  • wait_for_text_present(pattern) - -
  • -
  • wait_for_text_not_present(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 607
-607:   def store_text_present pattern, variable_name
-608:     command 'storeTextPresent', pattern, variable_name
-609:   end
-
-
-
-
- -
- - - - -
-

-Gets the title of the current page. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_title(pattern) - -
  • -
  • assert_not_title(pattern) - -
  • -
  • verify_title_present(pattern) - -
  • -
  • verify_not_title(pattern) - -
  • -
  • wait_for_title(pattern) - -
  • -
  • wait_for_not_title(pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 287
-287:   def store_title variable_name
-288:     command 'storeTitle', variable_name
-289:   end
-
-
-
-
- -
- - - - -
-

-Gets the (whitespace-trimmed) value of an input field (or anything else -with a value parameter). For checkbox/radio elements, the value will be -"on" or "off" depending on whether the element is -checked or not. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_value(locator, pattern) - -
  • -
  • assert_not_value(locator, pattern) - -
  • -
  • verify_value_present(locator, pattern) - -
  • -
  • verify_not_value(locator, pattern) - -
  • -
  • wait_for_value(locator, pattern) - -
  • -
  • wait_for_not_value(locator, pattern) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 315
-315:   def store_value locator, variable_name
-316:     command 'storeValue', locator, variable_name
-317:   end
-
-
-
-
- -
- - - - -
-

-Determines if the specified element is visible. An element can be rendered -invisible by setting the CSS "visibility" property to -"hidden", or the "display" property to -"none", either for the element itself or one if its ancestors. -This method will fail if the element is not present. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_visible(locator) - -
  • -
  • assert_not_visible(locator) - -
  • -
  • verify_visible(locator) - -
  • -
  • verify_not_visible(locator) - -
  • -
  • wait_for_visible(locator) - -
  • -
  • wait_for_not_visible(locator) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 636
-636:   def store_visible locator, variable_name
-637:     command 'storeVisible', locator, variable_name
-638:   end
-
-
-
-
- -
- - - - -
-

-Determine whether current/locator identify the frame containing this -running code. -

-

-This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to -identify the "current" frame. In this case, when the test calls -select_frame, this routine is called for each frame to figure out which one -has been selected. The selected frame will return true, while all others -will return false. -

-

-NOTE: store_whether_this_frame_match_frame_expression -is currently not supported by Selenium Core. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
  • assert_not_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
  • verify_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
  • verify_not_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
  • wait_for_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
  • wait_for_not_whether_this_frame_match_frame_expression(current_frame_string, -target) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 846
-846:   def store_whether_this_frame_match_frame_expression current_frame_string, target, variable_name
-847:     raise 'Not supported in Selenium Core at the moment'
-848:   end
-
-
-
-
- -
- - - - -
-

-Determine whether current_window_string plus target identify the window -containing this running code. -

-

-This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to -identify the "current" window. In this case, when the test calls -select_window, this routine is called for each window to figure out which -one has been selected. The selected window will return true, while all -others will return false. -

-

-NOTE: store_whether_this_window_match_window_expression -is currently not supported by Selenium Core. -

-

-Related Assertions, automatically generated: -

-
    -
  • assert_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
  • assert_not_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
  • verify_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
  • verify_not_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
  • wait_for_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
  • wait_for_not_whether_this_window_match_window_expression(current_window_string, -target) - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_accessors.rb, line 869
-869:   def store_whether_this_window_match_window_expression current_window_string, target, variable_name
-870:     raise 'Not supported in Selenium Core at the moment'
-871:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderActions.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderActions.html deleted file mode 100644 index b48104f2..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderActions.html +++ /dev/null @@ -1,2080 +0,0 @@ - - - - - - Module: SeleniumOnRails::TestBuilderActions - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::TestBuilderActions
In: - - lib/selenium_on_rails/test_builder_actions.rb - -
-
-
- - -
- - - -
- -
-

-The actions available for SeleniumOnRails::TestBuilder tests. -

-

-For each action foo there‘s also an action -foo_and_wait. -

- -
- - -
- - - -
- - - - -
- - - - - - - - - -
-

Public Instance methods

- -
- - - - -
-

-Add a selection to the set of selected options in a multi-select element using an option -locator. -

-

-See the select -command for more information about option locators. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 148
-148:   def add_selection locator, option_locator
-149:     command 'addSelection', locator, option_locator
-150:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user pressing the alt key and hold it down until do_alt_up() -is called or a new page is loaded. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 221
-221:   def alt_key_down
-222:     command 'altKeyDown'
-223:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user releasing the alt key. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 226
-226:   def alt_key_up
-227:     command 'altKeyUp'
-228:   end
-
-
-
-
- -
- - - - -
-

-Instructs Selenium to return the specified answer string in response to the -next JavaScript prompt (window.prompt()). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 199
-199:   def answer_on_next_prompt answer
-200:     command 'answerOnNextPrompt', answer
-201:   end
-
-
-
-
- -
- - - - -
-

-Halt the currently running test, and wait for the user to press the -Continue button. This command is useful for debugging, but be careful when -using it, because it will force automated tests to hang until a user -intervenes manually. -

-

-NOTE: break is a reserved word in Ruby, so we have to simulate -Selenium core‘s break() with brake() -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 236
-236:   def brake
-237:     command 'break'
-238:   end
-
-
-
-
- -
- - - - -
-

-Check a toggle-button (checkbox/radio). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 108
-108:   def check locator
-109:     command 'check', locator
-110:   end
-
-
-
-
- -
- - - - -
-

-By default, Selenium‘s overridden window.confirm() function -will return true, as if the user had manually clicked OK. After -running this command, the next call to confirm() will return -false, as if the user had clicked Cancel. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 193
-193:   def choose_cancel_on_next_confirmation
-194:     command 'chooseCancelOnNextConfirmation'
-195:   end
-
-
-
-
- -
- - - - -
-

-Clicks on a link, button, checkbox or radio button. If the click action causes a new page -to load (like a link usually does), call wait_for_page_to_load. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 47
-47:   def click locator
-48:     command 'click', locator
-49:   end
-
-
-
-
- -
- - - - -
-

-Clicks on a link, button, checkbox or radio button. If the click action causes a new page -to load (like a link usually does), call wait_for_page_to_load. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 53
-53:   def click_at locator, coord_string
-54:     command 'clickAt', locator, coord_string
-55:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user clicking the "close" button in the -titlebar of a popup window or tab. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 215
-215:   def close
-216:     command 'close'
-217:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user pressing the alt key and hold it down until -do_control_up() is called or a new page is loaded. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 242
-242:   def control_key_down
-243:     command 'controlKeyDown'
-244:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user releasing the control key. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 247
-247:   def control_key_up
-248:     command 'controlKeyUp'
-249:   end
-
-
-
-
- -
- - - - -
-

-Create a new cookie whose path and domain are same with those of current -page under test, unless you specified a path for this cookie explicitly. -

-

-Arguments: -

-
    -
  • name_value_pair - name and value of the cookie in a format -"name=value" - -
  • -
  • options_string - options for the cookie. Currently supported -options include ‘path’ and ‘max_age’. The -options_string‘s format is "path=/path/, -max_age=60". The order of options are irrelevant, the unit of the -value of ‘max_age’ is second. - -
  • -
-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 260
-260:   def create_cookie name_value_pair, options_string
-261:     command 'createCookie', name_value_pair, options_string
-262:   end
-
-
-
-
- -
- - - - -
-

-Delete a named cookie with specified path. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 265
-265:   def delete_cookie name, path
-266:     command 'deleteCookie', name, path
-267:   end
-
-
-
-
- -
- - - - -
-

-Double clicks on a link, button, checkbox or radio button. If the double click action causes a new page -to load (like a link usually does), call wait_for_page_to_load. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 271
-271:   def double_click locator
-272:     command 'doubleClick', locator
-273:   end
-
-
-
-
- -
- - - - -
-

-Doubleclicks on a link, button, checkbox or radio button. If the action -causes a new page to load (like a link usually does), call wait_for_page_to_load. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 277
-277:   def double_click_at locator, coord_string
-278:     command 'doubleClickAt', locator, coord_string
-279:   end
-
-
-
-
- -
- - - - -
-

-Drags an element a certain distance and then drops it. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 282
-282:   def drag_and_drop locator, movements_string
-283:     command 'dragAndDrop', locator, movements_string
-284:   end
-
-
-
-
- -
- - - - -
-

-Drags an element and drops it on another element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 287
-287:   def drag_and_drop_to_object locator_of_object_to_be_dragged, locator_of_drag_destination_object
-288:     command 'dragAndDropToObject', locator_of_object_to_be_dragged, locator_of_drag_destination_object
-289:   end
-
-
-
-
- -
- - - - -
-

-Prints the specified message into the third table cell in your Selenese tables. Useful for debugging. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 294
-294:   def echo message
-295:     command 'echo', message
-296:   end
-
-
-
-
- -
- - - - -
-

-Explicitly simulate an event (e.g. "focus", -"blur"), to trigger the corresponding -"on_event_" handler. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 59
-59:   def fire_event locator, event_name
-60:     command 'fireEvent', locator, event_name
-61:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user clicking the "back" button on their browser. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 204
-204:   def go_back
-205:     command 'goBack'
-206:   end
-
-
-
-
- -
- - - - -
-

-Briefly changes the backgroundColor of the specified element yellow. Useful -for debugging. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 300
-300:   def highlight locator
-301:     command 'highlight', locator
-302:   end
-
-
-
-
- -
- - - - -
-

-Includes a partial. The path is relative to the Selenium tests root. The -starting _ and the file extension don‘t have to be specified. -

-
-  #include test/selenium/_partial.*
-  include_partial 'partial'
-  #include test/selenium/suite/_partial.*
-  include_partial 'suite/partial'
-  #include test/selenium/suite/_partial.* and provide local assigns
-  include_partial 'suite/partial', :foo => bar
-
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 39
-39:   def include_partial path, local_assigns = {}
-40:     partial = @view.render :partial => path, :locals => local_assigns
-41:     @output << partial
-42:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user pressing a key (without releasing it yet). -

-

-keycode is the numeric keycode of the key to be pressed, normally -the ASCII value of that key. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 75
-75:   def key_down locator, keycode
-76:     command 'keyDown', locator, keycode
-77:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user pressing and releasing a key. -

-

-keycode is the numeric keycode of the key to be pressed, normally -the ASCII value of that key. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 67
-67:   def key_press locator, keycode
-68:     command 'keyPress', locator, keycode
-69:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user releasing a key. -

-

-keycode is the numeric keycode of the key to be released, normally -the ASCII value of that key. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 83
-83:   def key_up locator, keycode
-84:     command 'keyUp', locator, keycode
-85:   end
-
-
-
-
- -
- - - - -
-

-Press the meta key and hold it down until doMetaUp() is called or -a new page is loaded. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 306
-306:   def meta_key_down
-307:     command 'metaKeyDown'
-308:   end
-
-
-
-
- -
- - - - -
-

-Release the meta key. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 311
-311:   def meta_key_up
-312:     command 'metaKeyUp'
-313:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 94
-94:   def mouse_down locator
-95:     command 'mouseDown', locator
-96:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 317
-317:   def mouse_down_at locator, coord_string
-318:     command 'mouseDownAt', locator, coord_string
-319:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user moving the mouse. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 322
-322:   def mouse_move locator
-323:     command 'mouseMove', locator
-324:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user moving the mouse relative to the specified element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 327
-327:   def mouse_move_at locator, coord_string
-328:     command 'mouseMoveAt', locator, coord_string
-329:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user moving the mouse off the specified element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 332
-332:   def mouse_out locator
-333:     command 'mouseOut', locator
-334:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user hovering a mouse over the specified element. -

-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 88
-88:   def mouse_over locator
-89:     command 'mouseOver', locator
-90:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user releasing the mouse button on the specified element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 337
-337:   def mouse_up locator
-338:     command 'mouseUp', locator
-339:   end
-
-
-
-
- -
- - - - -
-

-Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 343
-343:   def mouse_up_at locator, coord_string
-344:     command 'mouseUpAt', locator, coord_string
-345:   end
-
-
-
-
- -
- - - - -
-

-Opens an URL in the test frame. This accepts both relative and absolute -URLs. The open -command waits for the page to load before proceeding, i.e. you don‘t -have to call wait_for_page_to_load. -

-

-Note: The URL must be on the same domain as the runner HTML due to security -restrictions in the browser (Same Origin Policy). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 172
-172:   def open url
-173:     command 'open', url_arg(url)
-174:   end
-
-
-
-
- -
- - - - -
-

-Opens a popup window (if a window with that ID isn‘t already open). After opening the window, -you‘ll need to select -it using the select_window command. -

-

-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). In -those cases, you can force Selenium to notice the open window‘s name by -using the Selenium openWindow command, using an empty (blank) url, like -this: open_window("", -"myFunnyWindow"). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 355
-355:   def open_window url, window_id
-356:     command 'openWindow', url, window_id
-357:   end
-
-
-
-
- -
- - - - -
-

-Wait for the specified amount of time (in milliseconds). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 360
-360:   def pause wait_time
-361:     command 'pause', wait_time
-362:   end
-
-
-
-
- -
- - - - -
-

-Simulates the user clicking the "Refresh" button on their -browser. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 209
-209:   def refresh
-210:     command 'refresh'
-211:   end
-
-
-
-
- -
- - - - -
-

-Unselects all of the selected options in a multi-select element. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 365
-365:   def remove_all_selections locator
-366:     command 'removeAllSelections', locator
-367:   end
-
-
-
-
- -
- - - - -
-

-Remove a selection from the set of selected options in a multi-select element using an option -locator. -

-

-See the select -command for more information about option locators. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 156
-156:   def remove_selection locator, option_locator
-157:     command 'removeSelection', locator, option_locator
-158:   end
-
-
-
-
- -
- - - - -
-

-Select an option from a drop-down using an option locator. -

-

-Option locators provide different ways of specifying options of an HTML -Select element (e.g. for selecting a specific option, or for asserting that -the selected option satisfies a specification). There are several forms of -Select Option Locator. -

-
    -
  • label=labelPattern matches options based on their labels, i.e. the visible -text. (This is the default.) - -
    -  label=regexp:^[Oo]ther
    -
    -
  • -
  • value=valuePattern matches options based on their values. - -
    -  value=other
    -
    -
  • -
  • id=id matches options based on their ids. - -
    -  id=option1
    -
    -
  • -
  • index=index matches an option based on its index (offset from zero). - -
    -  index=2
    -
    -
  • -
-

-If no option locator prefix is provided, the default behaviour is to match -on label. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 140
-140:   def select locator, option_locator
-141:     command 'select', locator, option_locator
-142:   end
-
-
-
-
- -
- - - - -
-

-Selects a frame within the current window. (You may invoke this command -multiple times to select -nested frames.) To select the -parent frame, use "relative=parent" as a locator; to select the top frame, use -"relative=top". -

-

-You may also use a DOM expression to identify the frame you want directly, -like this: dom=frames["main"].frames -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 375
-375:   def select_frame locator
-376:     command 'selectFrame', locator
-377:   end
-
-
-
-
- -
- - - - -
-

-Selects a popup window; once a popup window has been selected, all commands -go to that window. To select -the main window again, use nil as the target. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 178
-178:   def select_window window_id
-179:     command 'selectWindow', window_id||'null'
-180:   end
-
-
-
-
- -
- - - - -
-

-Writes a message to the status bar and adds a note to the browser-side log. -

-

-context is the message sent to the browser. -

-

-log_level_threshold can be nil, :debug, -:info, :warn or :error. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 448
-448:   def set_context context, log_level_threshold = nil
-449:     if log_level_threshold
-450:       command 'setContext', context, log_level_threshold.to_s
-451:     else
-452:       command 'setContext', context
-453:     end
-454:   end
-
-
-
-
- -
- - - - -
-

-Moves the text cursor to the specified position in the given input element -or textarea. This method will fail if the specified element isn‘t an -input element or textarea. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 381
-381:   def set_cursor_position locator, position
-382:     command 'setCursorPosition', locator, position
-383:   end
-
-
-
-
- -
- - - - -
-

-Configure the number of pixels between "mousemove" events during -dragAndDrop commands (default=10). Setting this value to 0 means that -we‘ll send a "mousemove" event to every single pixel in -between the start location and the end location; that can be very slow, and -may cause some browsers to force the JavaScript to timeout. -

-

-If the mouse speed is greater than the distance between the two dragged -objects, we‘ll just send one "mousemove" at the start -location and then one final one at the end location. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 393
-393:   def set_mouse_speed pixels
-394:     command 'setMouseSpeed', pixels
-395:   end
-
-
-
-
- -
- - - - -
-

-Specifies the amount of time that Selenium will wait for actions to -complete. -

-

-Actions that require waiting include open and the -wait_for* actions. -

-

-The default timeout is 30 seconds. -

-

-timeout is specified in milliseconds. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 480
-480:   def set_timeout timeout
-481:     command 'setTimeout', timeout
-482:   end
-
-
-
-
- -
- - - - -
-

-Tell Selenium on Rails to clear the session and load any fixtures. DO NOT -CALL THIS AGAINST NON-TEST DATABASES. The supported options are -:keep_session, :fixtures and :clear_tables -

-
-  setup
-  setup :keep_session
-  setup :fixtures => :all
-  setup :keep_session, :fixtures => [:foo, :bar]
-  setup :clear_tables => [:foo, :bar]
-
-

[Source]

-
-
-    # File lib/selenium_on_rails/test_builder_actions.rb, line 14
-14:   def setup options = {}
-15:     options = {options => nil} unless options.is_a? Hash
-16: 
-17:     opts = {:controller => 'selenium', :action => 'setup'}
-18:     opts[:keep_session] = true if options.has_key? :keep_session
-19: 
-20:     [:fixtures, :clear_tables].each do |key|
-21:       if (f = options[key])
-22:         f = [f] unless f.is_a? Array
-23:         opts[key] = f.join ','
-24:       end
-25:     end
-26: 
-27:     open opts
-28:   end
-
-
-
-
- -
- - - - -
-

-Press the shift key and hold it down until doShiftUp() is called -or a new page is loaded. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 399
-399:   def shift_key_down
-400:     command 'shiftKeyDown'
-401:   end
-
-
-
-
- -
- - - - -
-

-Release the shift key. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 404
-404:   def shift_key_up
-405:     command 'shiftKeyUp'
-406:   end
-
-
-
-
- -
- - - - -
-

-This command is a synonym for store_expression. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 409
-409:   def store expression, variable_name
-410:     command 'store', expression, variable_name
-411:   end
-
-
-
-
- -
- - - - -
-

-Submit the specified form. This is particularly useful for forms without submit buttons, e.g. -single-input "Search" forms. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 162
-162:   def submit locator
-163:     command 'submit', locator
-164:   end
-
-
-
-
- -
- - - - -
-

-Sets the value of an input field, as though you typed it in. -

-

-Can also be used to set the value of combo boxes, check boxes, etc. In these -cases, value should be the value of the option selected, not the -visible text. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 103
-103:   def type locator, value
-104:     command 'type', locator, value
-105:   end
-
-
-
-
- -
- - - - -
-

-Simulates keystroke events on the specified element, as though you typed -the value key-by-key. -

-

-This is a convenience method for calling key_down, key_up, key_press for every -character in the specified string; this is useful for dynamic UI widgets -(like auto-completing combo boxes) that require explicit key events. -

-

-Unlike the simple "type" command, which forces -the specified value into the page directly, this command may or may not -have any visible effect, even in cases where typing keys would normally -have a visible effect. For example, if you use "type_keys" on a form -element, you may or may not see the results of what you typed in the field. -

-

-In some cases, you may need to use the simple "type" command to set the -value of the field and then the "type_keys" command to -send the keystroke events corresponding to what you just typed. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 428
-428:   def type_keys locator, value
-429:     command 'typeKeys', locator, value
-430:   end
-
-
-
-
- -
- - - - -
-

-Uncheck a toggle-button (checkbox/radio). -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 113
-113:   def uncheck locator
-114:     command 'uncheck', locator
-115:   end
-
-
-
-
- -
- - - - -
-

-Runs the specified JavaScript snippet repeatedly until it evaluates to -true. The snippet may have multiple lines, but only the result of -the last line will be considered. -

-

-Note that, by default, the snippet will be run in the runner‘s test -window, not in the window of your application. To get the window of your -application, you can use the JavaScript snippet -selenium.browserbot.getCurrentWindow(), and then run your -JavaScript in there. -

-

-timeout is specified in milliseconds. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 467
-467:   def wait_for_condition script, timeout
-468:     command 'waitForCondition', script, timeout
-469:   end
-
-
-
-
- -
- - - - -
-

-Waits for a new page to load. -

-

-You can use this command instead of the and_wait suffixes, -click_and_wait, select_and_wait, type_and_wait -etc. (which are only available in the JS API). -

-

-Selenium constantly keeps track of new pages loading, and sets a -newPageLoaded flag when it first notices a page load. Running any -other Selenium command after turns the flag to false. Hence, if -you want to wait for a page to load, you must wait immediately after a -Selenium command that caused a page-load. -

-

-timeout is specified in milliseconds. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 497
-497:   def wait_for_page_to_load timeout
-498:     command 'waitForPageToLoad', timeout
-499:   end
-
-
-
-
- -
- - - - -
-

-Waits for a popup window to appear and load up. -

-

-The timeout is specified in milliseconds. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 185
-185:   def wait_for_popup window_id, timeout
-186:     command 'waitForPopUp', window_id||'null', timeout
-187:   end
-
-
-
-
- -
- - - - -
-

-Gives focus to a window. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 433
-433:   def window_focus window_name
-434:     command 'windowFocus', window_name
-435:   end
-
-
-
-
- -
- - - - -
-

-Resize window to take up the entire screen. -

-

[Source]

-
-
-     # File lib/selenium_on_rails/test_builder_actions.rb, line 438
-438:   def window_maximize window_name
-439:     command 'windowMaximize', window_name
-440:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserAccessors.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserAccessors.html deleted file mode 100644 index 8b2d19aa..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserAccessors.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Module: SeleniumOnRails::TestBuilderUserAccessors - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::TestBuilderUserAccessors
In: - - lib/selenium_on_rails/test_builder.rb - -
-
-
- - -
- - - -
- -
-

-Create test_builder_user_accessors.rb to support accessors included in -selenium-core‘s user-extensions.js -

-

-See test_builder_user_accessors.rb.example for examples matching -selenium-core‘s user-extensions.js.sample -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserActions.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserActions.html deleted file mode 100644 index b163ba01..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserActions.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Module: SeleniumOnRails::TestBuilderUserActions - - - - - - - - - - -
- - - - - - - - - - -
ModuleSeleniumOnRails::TestBuilderUserActions
In: - - lib/selenium_on_rails/test_builder.rb - -
-
-
- - -
- - - -
- -
-

-Create test_builder_user_actions.rb to support actions included in -selenium-core‘s user-extensions.js -

-

-See test_builder_user_actions.rb.example for examples matching -selenium-core‘s user-extensions.js.sample -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRailsConfig.html b/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRailsConfig.html deleted file mode 100644 index 4fae21bf..00000000 --- a/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRailsConfig.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - Class: SeleniumOnRailsConfig - - - - - - - - - - -
- - - - - - - - - - - - - - -
ClassSeleniumOnRailsConfig
In: - - lib/selenium_on_rails_config.rb - -
-
Parent: - Object -
-
- - -
- - - -
- - - -
- -
-

Methods

- -
- get   -
-
- -
- - - - -
- - - - - - - - - -
-

Public Class methods

- -
- - - - -
-

[Source]

-
-
-    # File lib/selenium_on_rails_config.rb, line 5
- 5:   def self.get var, default = nil
- 6:     value = configs[var.to_s]
- 7:     value ||= @@defaults[var]
- 8:     value ||= default
- 9:     value ||= yield if block_given?
-10:     value
-11:   end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/CHANGELOG.html b/vendor/plugins/selenium-on-rails/doc/files/CHANGELOG.html deleted file mode 100644 index e367af7f..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/CHANGELOG.html +++ /dev/null @@ -1,422 +0,0 @@ - - - - - - File: CHANGELOG - - - - - - - - - - -
-

CHANGELOG

- - - - - - - - - -
Path:CHANGELOG -
Last Update:Sat Feb 03 23:49:15 +0100 2007
-
- - -
- - - -
- -
-

REVISION 38

-

change made by Flanagan

-
    -
  • SOR-13 Corrected an -omission of require statements. - -
  • -
-

REVISION 37

-

change made by Flanagan

-
    -
  • Undone an unwanted commit of modified Rakefile. - -
  • -
-

REVISION 36

-

change made by Flanagan

-
    -
  • SOR-13 Added -(experimental) support for user-extensions.js. - -
  • -
-

REVISION 35

-

all changes made by Jonas

-
    -
  • SOR-12 removed all -support for selenium gem - -
  • -
  • Selenium Core 0.8.2 is now bundled with Selenium on Rails. If you want to -use other version set the ‘selenium_path’ in config.yml - -
  • -
  • Updated installation instructions for Windows - -
  • -
-

REVISION 34

-

all changes made by Flanagan

-
    -
  • SOR-11 Fixed related -assertions for store_checked to use only locator parameter - -
  • -
-

-Warning: Users must change tests that pass two parameters (locator, -pattern) to verify_checked, verify_not_checked, -assert_checked, assert_not_checked, -wait_for_checked, or wait_for_not_checked. -

-

-Test scripts that continue to use two parameters will be broken, only one -parameter, the locator, should be passed. -

-

-For example, |verify_checked|my_checkbox|true| will be interpreted -as |verify_checked|my_checkboxtrue|| so change the test to -|verify_checked|my_checkbox|| -

-
    -
  • SOR-9 Added Mac OS X -browsers to config.yml.example - -
  • -
  • SOR-10 Added support for -baseUrl to acceptance_test_runner.rb as added to selenium-core 0.8.2 - -
  • -
  • Added ‘webrick’ to SERVER_COMMAND in acceptance_test_runner.rb -as parameters do not work with lighttpd - -
  • -
  • Reversed expected query string in test/renderer_testrb to make tests pass - -
  • -
-

-Note: On Mac OS X, at least, clear_tables comes before fixtures in the -query string; this may be an environment-specific issue if the test now -fails on other OSes. -

-
    -
  • Added this CHANGELOG file and amended the rake rdoc task to include it - -
  • -
  • Added support in rselenese for a long list of actions and accessors that -are included in selenium-core (0.8.2 and possibly earlier) but were -previously missing in selenium-on-rails. - -
  • -
-

-Here are the newly supported actions: -

-

-Useful for debugging: -

-
    -
  • brake (alias for selenium-core‘s break, a reserved word in -Ruby) - -
  • -
  • echo, :string - -
  • -
  • highlight, :locator - -
  • -
-

-Keyboard events: -

-
    -
  • alt_key_down - -
  • -
  • alt_key_up - -
  • -
  • control_key_down - -
  • -
  • control_key_up - -
  • -
  • meta_key_down - -
  • -
  • meta_key_up - -
  • -
  • shift_key_down - -
  • -
  • shift_key_up - -
  • -
  • type_keys, :locator, :string - -
  • -
-

-Mouse events: -

-
    -
  • click_at, :locator, :coord_string - -
  • -
  • double_click, :locator - -
  • -
  • double_click_at, :locator, :coord_string - -
  • -
  • drag_and_drop, :locator, :movements_string - -
  • -
  • drag_and_drop_to_object, :locator, :locator - -
  • -
  • mouse_down_at, :locator, :coord_string - -
  • -
  • mouse_move, :locator - -
  • -
  • mouse_move_at, :locator, :coord_string - -
  • -
  • mouse_out, :locator - -
  • -
  • mouse_up, :locator - -
  • -
  • mouse_up_at, :locator, :coord_string - -
  • -
  • set_mouse_speed, :integer - -
  • -
-

-Other actions: -

-
    -
  • create_cookie, :name_value_pair, :options_string - -
  • -
  • delete_cookie, :string, :string - -
  • -
  • open_window, :url, :integer - -
  • -
  • pause, :timeout - -
  • -
  • remove_all_selections, :locator - -
  • -
  • select_frame, :locator - -
  • -
  • set_cursor_position, :locator, :integer - -
  • -
  • store, :script, :variable - -
  • -
  • window_focus, :window_name - -
  • -
  • window_maximize, :window_name - -
  • -
-

-Here are the newly supported accessors: -

-

-The following store_* accessors and their associated assert, verify and -wait_for brethren are fully supported: -

-
    -
  • store_selected_id, :locator, :variable - -
  • -
  • store_selected_ids, :locator, :variable - -
  • -
  • store_selected_index, :locator, :variable - -
  • -
  • store_selected_indexes, :locator, :variable - -
  • -
  • store_selected_label, :locator, :variable - -
  • -
  • store_selected_labels, :locator, :variable - -
  • -
  • store_selected_value, :locator, :variable - -
  • -
  • store_selected_values, :locator, :variable - -
  • -
  • store_something_selected, :locator, :variable - -
  • -
  • store_all_window_ids, :variable - -
  • -
  • store_all_window_names, :variable - -
  • -
  • store_all_window_titles, :variable - -
  • -
  • store_cookie, :variable - -
  • -
  • store_log_messages, :variable - -
  • -
  • store_mouse_speed, :variable - -
  • -
  • store_cursor_position, :locator, :variable - -
  • -
  • store_attribute_from_all_windows, :attribute_name, :variable - -
  • -
  • store_element_height, :locator, :variable - -
  • -
  • store_element_index, :locator, :variable - -
  • -
  • store_element_width, :locator, :variable - -
  • -
  • store_element_position_left, :locator, :variable - -
  • -
  • store_element_position_top, :locator, :variable - -
  • -
-

-Only the associated assert, verify and wait_for brethren of the following -store_* accessors are supported by the selenium-core, so these store_* -accessors create exceptions in SOR: -

-
    -
  • store_ordered, :locator, :locator, :variable - -
  • -
  • store_error_on_next, :string - -
  • -
  • store_failure_on_next, :string - -
  • -
  • store_whether_this_frame_match_frame_expression, :string, :string, -:variable - -
  • -
  • store_whether_this_window_match_window_expression, :string, :string, -:variable - -
  • -
- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/README.html b/vendor/plugins/selenium-on-rails/doc/files/README.html deleted file mode 100644 index 2984f6f9..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/README.html +++ /dev/null @@ -1,321 +0,0 @@ - - - - - - File: README - - - - - - - - - - -
-

README

- - - - - - - - - -
Path:README -
Last Update:Sat Feb 03 22:54:11 +0100 2007
-
- - -
- - - -
- -
-

Welcome to the Selenium on Rails README. Exciting isn’t it?

- -

Selenium on Rails

- -

Overview

- -

Selenium on Rails provides an easy way to test Rails application with - SeleniumCore[http://www.openqa.org/selenium-core/].

- -

This plugin does four things:

- -
    -
  1. The Selenium Core files don’t have to pollute /public.
  2. -
  3. No need to create suite files, they are generated on the fly — one suite per directory in /test/selenium (suites can be nested).
  4. -
  5. Instead of writing the test cases in HTML you can use a number of better formats (see Formats).
  6. -
  7. Loading of fixtures and wiping of session (/selenium/setup).
  8. -
- -

Installation

- -

Rails periodically changes the way that it renders pages, which unfortunately breaks backwards versions of Selenium on Rails. Therefore there are different - installation locations depending on your version of Rails:

- -

Rails 2.2 and up:

- -
http://svn.openqa.org/svn/selenium-on-rails/stable/selenium-on-rails
-	
- -

Rails 2.1:

- -
http://svn.openqa.org/svn/selenium-on-rails/tags/rails_2_1/selenium-on-rails
-	
- -

Before Rails 2.1:

- -
http://svn.openqa.org/svn/selenium-on-rails/tags/pre-rails-2-1/selenium-on-rails
-	
- -

The latest release is always kept on GitHub at

- -
git clone git://github.com/paytonrules/selenium-on-rails.git
-	
- -

To install:

- -
    -
  1. Install Selenium on Rails: script/plugin install
  2. -
  3. If you‘re on Windows, gem install win32-open3
  4. -
  5. If the RedCloth gem is available the Selenese test cases can use it for better markup.
  6. -
  7. Run the Rakefile in the plugin‘s directory to run the tests in order to see that everything works. (If RedCloth isn‘t installed a few tests will fail since they assume RedCloth is installed.)
  8. -
  9. Create a test case: script/generate selenium
  10. -
  11. Start the server: script/server -e test
  12. -
  13. Point your browser to localhost:3000/selenium
  14. -
  15. If everything works as expected you should see the Selenium test runner. The north east frame contains all your test cases (just one for now), and the north frame contains your test case.
  16. -
- -

Formats

- -

The test cases can be written in a number of formats. Which one you choose is a matter of taste. You can generate your test files by running script/generate selenium or by creating them manually in your /test/selenium directory.

- -

RSelenese, .rsel

- -

RSelenese lets you write your tests in Ruby. This is my favorite format.

- -
setup :fixtures => :all
-	open '/'
-	assert_title 'Home'
-	('a'..'z').each {|c| open :controller => 'user', :action => 'create', :name => c }
-	
- -

See SeleniumOnRails::TestBuilder for available commands. IMPORTANT NOTE: RSelenese generates the HTML tables for Selenium behind the scenes when the page is loaded - ONCE. That means code like this:

- -
(1..10).each do |index|
-	    do something
-	end
-	
- -

Will only be executed when the test is loaded, not when the test is run. This is a common error and leads to tests that work the first time and fail the second time.

- -

Selenese, .sel

- -

Selenese is the dumbest format (in a good way). You just write your commands delimited by | characters.

- -
|open|/selenium/setup|
-	|open|/|
-	|goBack|
-	
- -

If you don‘t want to write Selenese tests by hand you can use SeleniumIDE which has support for Selenese.

- -

HTML/RHTML

- -

You can write your tests in HTML/RHTML but that‘s mostly useful if you have existing tests you want to reuse.

- -

Partial test cases

- -

If you have some common actions you want to do in several test cases you can put them in a separate partial test case and include them in your other test cases. This is highly recommended, just as small functions would be recommended in structured programming.

- -

A partial test case is just like a normal test case besides that its filename has to start with _:

- -
#_login.rsel
-	open '/login'
-	type 'name', name
-	type 'password', password
-	click 'submit', :wait=>true
-	
- -

To include a partial test case in a RSelenese test case:

- -
include_partial 'login', :name => 'Jane Doe', :password => 'Jane Doe'.reverse
-	
- -

in a Selenese test case:

- -
|includePartial|login|name=John Doe|password=eoD nhoJ|
-	
- -

and in a RHTML test case:

- -
<%= render :partial => 'login', :locals => {:name = 'Joe Schmo', :password => 'Joe Schmo'.reverse} %>
-	
- -

Configuration

- -

There are a number of settings available. You make them by renaming selenium.yml.example to selenium.yml and placing it in your rails app’s config - file. Make your changes in that file.

- -

Environments

- -

Per default this plugin is only available in test environment. You can change this by setting environments, such as:

- -
#selenium.yml
-	environments:
-	    - test
-	    - development
-	
- -

Selenium Core path

- -

If you don‘t want to use the bundled Selenium Core version you can set selenium_path to the directory where Selenium Core is stored.

- -
#config.yml
-	selenium_path: 'c:\selenium'
-	
- -

Rake Task

- -

You can run all your Selenium tests as a Rake task. If you’re using a continuous builder this is a great way to integrate selenium into your build process. First, if you‘re on Windows, you have to make sure win32-open3 is installed. Then you have to configure which browsers you want to run, like this:

- -
#config.yml
-	browsers:
-	    firefox: 'c:\Program Files\Mozilla Firefox\firefox.exe'
-	    ie: 'c:\Program Files\Internet Explorer\iexplore.exe'
-	
- -

Now you‘re all set. First start a server:

- -
script/server -e test
-	
- -

Then run the tests:

- -
rake test:acceptance
-	
- -

Now it should work, otherwise let me know!

- -

Store results

- -

If you want to store the results from a test:acceptance you just need to set in which directory they should be stored:

- -
#config.yml
-	result_dir: 'c:\result'
-	
- -

So when you run rake test:acceptance the tables with the results will be stored as .html files in that directory.

- -

user_extension.js

- -

Selenium has support for user_extension.js which is a way to extend the functionality of Selenium Core. Selenium on Rails now provides the means for you to extend it’s functionality to match.

- -

To get you started, we’ve included the example files lib/test_builder_user_accessors.rb.example and lib/test_builder_user_actions.rb.example that replicate the sample extensions in Selenium Core’s user-extensions.js.sample.

- -

To get these examples running, simply remove the .example and .sample extensions - from the files and restart your server.

- -

Todo

- -
    -
  • Standalone mode - More work is needed on test:acceptance< on Windows to be able to start the server when needed.

  • -
  • Documentation update

  • -
- -

Not todo

- -
    -
  • Editor - Creating an editor for the test cases is currently considered out of scope for this plugin. SeleniumIDE[http://www.openqa.org/selenium-ide/] does such a good job and has support[http://wiki.openqa.org/display/SIDE/SeleniumOnRails] for both the Selenese and RSelenese formats.
  • -
- -

Credits

- -
    -
  • Jonas Bengston — original creator
  • -
  • Eric Smith, http://blog.8thlight.com/eric — Current Maintainer
  • -
  • Jon Tirsen, http://jutopia.tirsen.com — initial inspiration[http://wiki.rubyonrails.com/rails/pages/SeleniumIntegration]
  • -
  • Eric Kidd, http://www.randomhacks.net — contribution of RSelenese
  • -
  • Marcos Tapajós http://www.improveit.com.br/en/company/tapajos — Several useful features, current committer
  • -
  • Ryan Bates, http://railscasts.com — Fixes for Rails 2.1
  • -
  • Nando Vieira, http://simplesideias.com.br
  • -
  • Gordon McCreight, a neat script that lists any unsupported methods
  • -
- -

Contributing ##

- -

Contributing is simple. Fork this repo, make your changes, then issue a pull request. IMPORTANT I will not take forks that do not have associated unit tests. There must be tests, and they must pass, so I can bring the changes in.

- -

Information

- -

For more information, check out the website.

- - - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/controllers/selenium_controller_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/controllers/selenium_controller_rb.html deleted file mode 100644 index c2048237..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/controllers/selenium_controller_rb.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - File: selenium_controller.rb - - - - - - - - - - -
-

selenium_controller.rb

- - - - - - - - - -
Path:lib/controllers/selenium_controller.rb -
Last Update:Sat Feb 03 22:54:05 +0100 2007
-
- - -
- - - -
- - -
-

Required files

- -
- webrick/httputils   -
-
- -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_helper_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_helper_rb.html deleted file mode 100644 index b3e1c97e..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_helper_rb.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - File: selenium_helper.rb - - - - - - - - - - -
-

selenium_helper.rb

- - - - - - - - - -
Path:lib/selenium_helper.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/acceptance_test_runner_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/acceptance_test_runner_rb.html deleted file mode 100644 index 46a8c324..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/acceptance_test_runner_rb.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - File: acceptance_test_runner.rb - - - - - - - - - - -
-

acceptance_test_runner.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/acceptance_test_runner.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - -
-

Required files

- -
- net/http   - tempfile   -
-
- -
- -
-

Methods

- -
- c   - c_b   -
-
- -
- - - - -
- - -
-

Constants

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BROWSERS=c :browsers, {}
REUSE_EXISTING_SERVER=c :reuse_existing_server, true
START_SERVER=c :start_server, false
HOST=c :host, 'localhost'
PORTS=c(:port_start, 3000)..c(:port_end, 3005)
BASE_URL_PATH=c :base_url_path, '/'
TEST_RUNNER_URL=c :test_runner_url, '/selenium/TestRunner.html'
MAX_BROWSER_DURATION=c :max_browser_duration, 2*60
MULTI_WINDOW=c :multi_window, false
SERVER_COMMAND=c_b :server_command do server_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../script/server')
-
-
- - - - - - - -
-

Public Instance methods

- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_on_rails/acceptance_test_runner.rb, line 7
-7: def c(var, default = nil) SeleniumOnRailsConfig.get var, default end
-
-
-
-
- -
- - - - -
-

[Source]

-
-
-   # File lib/selenium_on_rails/acceptance_test_runner.rb, line 8
-8: def c_b(var, default = nil) SeleniumOnRailsConfig.get(var, default) { yield } end
-
-
-
-
- - -
- - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/fixture_loader_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/fixture_loader_rb.html deleted file mode 100644 index 8c2157ee..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/fixture_loader_rb.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - File: fixture_loader.rb - - - - - - - - - - -
-

fixture_loader.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/fixture_loader.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - -
-

Required files

- -
- test/unit   - active_record/fixtures   -
-
- -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/partials_support_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/partials_support_rb.html deleted file mode 100644 index 4b981a54..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/partials_support_rb.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - File: partials_support.rb - - - - - - - - - - -
-

partials_support.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/partials_support.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- -
-

-Provides partials support to test cases so they can include other partial -test cases. -

-

-The partial‘s commands are returned as html table rows. -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/paths_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/paths_rb.html deleted file mode 100644 index 5e688d5b..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/paths_rb.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - File: paths.rb - - - - - - - - - - -
-

paths.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/paths.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/renderer_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/renderer_rb.html deleted file mode 100644 index 0774a973..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/renderer_rb.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - File: renderer.rb - - - - - - - - - - -
-

renderer.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/renderer.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/rselenese_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/rselenese_rb.html deleted file mode 100644 index 38ccc73b..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/rselenese_rb.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - File: rselenese.rb - - - - - - - - - - -
-

rselenese.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/rselenese.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- -
-

-Renders Selenium test templates in a fashion analogous to rxml and -rjs templates. -

-
-  setup
-  open :controller => 'customer', :action => 'list'
-  assert_title 'Customers'
-
-

-See SeleniumOnRails::TestBuilder -for a list of available commands. -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/selenese_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/selenese_rb.html deleted file mode 100644 index 1f40e1c4..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/selenese_rb.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - File: selenese.rb - - - - - - - - - - -
-

selenese.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/selenese.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/suite_renderer_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/suite_renderer_rb.html deleted file mode 100644 index 4ec5b7e0..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/suite_renderer_rb.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - File: suite_renderer.rb - - - - - - - - - - -
-

suite_renderer.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/suite_renderer.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_accessors_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_accessors_rb.html deleted file mode 100644 index c375cd5e..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_accessors_rb.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - File: test_builder_accessors.rb - - - - - - - - - - -
-

test_builder_accessors.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/test_builder_accessors.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- -
-

-The accessors available for SeleniumOnRails::TestBuilder -tests. -

-

-For each store_foo there‘s assert_foo, -assert_not_foo, verify_foo, verify_not_foo, -wait_for_foo, wait_for_not_foo. -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_actions_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_actions_rb.html deleted file mode 100644 index 2896def6..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_actions_rb.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - File: test_builder_actions.rb - - - - - - - - - - -
-

test_builder_actions.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/test_builder_actions.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- -
-

-The actions available for SeleniumOnRails::TestBuilder -tests. -

-

-For each action foo there‘s also an action -foo_and_wait. -

- -
- - -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_rb.html deleted file mode 100644 index 4c5a5962..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_rb.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - File: test_builder.rb - - - - - - - - - - -
-

test_builder.rb

- - - - - - - - - -
Path:lib/selenium_on_rails/test_builder.rb -
Last Update:Sat Feb 03 23:42:13 +0100 2007
-
- - -
- - - -
- -
-

-Create test_builder_user_actions.rb to support actions included in -selenium-core‘s user-extensions.js -

-

-See test_builder_user_actions.rb.example for examples matching -selenium-core‘s user-extensions.js.sample -

- -
- -
-

Required files

- -
- selenium_on_rails/test_builder_user_actions   - selenium_on_rails/test_builder_user_accessors   -
-
- -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_config_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_config_rb.html deleted file mode 100644 index 042a702b..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_config_rb.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - File: selenium_on_rails_config.rb - - - - - - - - - - -
-

selenium_on_rails_config.rb

- - - - - - - - - -
Path:lib/selenium_on_rails_config.rb -
Last Update:Sat Feb 03 22:54:06 +0100 2007
-
- - -
- - - -
- - -
-

Required files

- -
- yaml   -
-
- -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_rb.html b/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_rb.html deleted file mode 100644 index 5d664b29..00000000 --- a/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_rb.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - File: selenium_on_rails.rb - - - - - - - - - - -
-

selenium_on_rails.rb

- - - - - - - - - -
Path:lib/selenium_on_rails.rb -
Last Update:Sat Feb 03 23:38:50 +0100 2007
-
- - -
- - - -
- - -
-

Required files

- -
- selenium_on_rails/selenese   - selenium_on_rails/test_builder   - selenium_on_rails/rselenese   - selenium_on_rails/suite_renderer   - selenium_on_rails/paths   - selenium_on_rails/fixture_loader   - selenium_on_rails/partials_support   - selenium_on_rails/renderer   -
-
- -
- - -
- - - - -
- - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/fr_class_index.html b/vendor/plugins/selenium-on-rails/doc/fr_class_index.html deleted file mode 100644 index 9109fec5..00000000 --- a/vendor/plugins/selenium-on-rails/doc/fr_class_index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - Classes - - - - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/fr_file_index.html b/vendor/plugins/selenium-on-rails/doc/fr_file_index.html deleted file mode 100644 index 06a0126b..00000000 --- a/vendor/plugins/selenium-on-rails/doc/fr_file_index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - Files - - - - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/fr_method_index.html b/vendor/plugins/selenium-on-rails/doc/fr_method_index.html deleted file mode 100644 index 6ea4dace..00000000 --- a/vendor/plugins/selenium-on-rails/doc/fr_method_index.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - Methods - - - - - -
-

Methods

-
- add_selection (SeleniumOnRails::TestBuilderActions)
- alt_key_down (SeleniumOnRails::TestBuilderActions)
- alt_key_up (SeleniumOnRails::TestBuilderActions)
- answer_on_next_prompt (SeleniumOnRails::TestBuilderActions)
- available_fixtures (SeleniumOnRails::FixtureLoader)
- brake (SeleniumOnRails::TestBuilderActions)
- c (lib/selenium_on_rails/acceptance_test_runner.rb)
- c_b (lib/selenium_on_rails/acceptance_test_runner.rb)
- check (SeleniumOnRails::TestBuilderActions)
- choose_cancel_on_next_confirmation (SeleniumOnRails::TestBuilderActions)
- clear_tables (SeleniumOnRails::FixtureLoader)
- click (SeleniumOnRails::TestBuilderActions)
- click_at (SeleniumOnRails::TestBuilderActions)
- close (SeleniumOnRails::TestBuilderActions)
- collection_arg (SeleniumOnRails::TestBuilder)
- command (SeleniumOnRails::TestBuilder)
- command_and_wait (SeleniumOnRails::TestBuilder)
- command_verbatim (SeleniumOnRails::TestBuilder)
- control_key_down (SeleniumOnRails::TestBuilderActions)
- control_key_up (SeleniumOnRails::TestBuilderActions)
- create_cookie (SeleniumOnRails::TestBuilderActions)
- delete_cookie (SeleniumOnRails::TestBuilderActions)
- double_click (SeleniumOnRails::TestBuilderActions)
- double_click_at (SeleniumOnRails::TestBuilderActions)
- drag_and_drop (SeleniumOnRails::TestBuilderActions)
- drag_and_drop_to_object (SeleniumOnRails::TestBuilderActions)
- echo (SeleniumOnRails::TestBuilderActions)
- exactize (SeleniumOnRails::TestBuilder)
- extract_commands_from_partial (SeleniumOnRails::PartialsSupport)
- fire_event (SeleniumOnRails::TestBuilderActions)
- fixtures_path (SeleniumOnRails::Paths)
- get (SeleniumOnRailsConfig)
- go_back (SeleniumOnRails::TestBuilderActions)
- highlight (SeleniumOnRails::TestBuilderActions)
- include_partial (SeleniumOnRails::TestBuilderActions)
- key_down (SeleniumOnRails::TestBuilderActions)
- key_press (SeleniumOnRails::TestBuilderActions)
- key_up (SeleniumOnRails::TestBuilderActions)
- layout_path (SeleniumOnRails::Paths)
- link_to_test_case (SeleniumOnRails::SuiteRenderer)
- load_fixtures (SeleniumOnRails::FixtureLoader)
- log_path (SeleniumOnRails::Paths)
- make_command_waiting (SeleniumOnRails::TestBuilder)
- meta_key_down (SeleniumOnRails::TestBuilderActions)
- meta_key_up (SeleniumOnRails::TestBuilderActions)
- mouse_down (SeleniumOnRails::TestBuilderActions)
- mouse_down_at (SeleniumOnRails::TestBuilderActions)
- mouse_move (SeleniumOnRails::TestBuilderActions)
- mouse_move_at (SeleniumOnRails::TestBuilderActions)
- mouse_out (SeleniumOnRails::TestBuilderActions)
- mouse_over (SeleniumOnRails::TestBuilderActions)
- mouse_up (SeleniumOnRails::TestBuilderActions)
- mouse_up_at (SeleniumOnRails::TestBuilderActions)
- new (SeleniumOnRails::TestBuilder)
- new (SeleniumOnRails::RSelenese)
- new (SeleniumOnRails::Selenese)
- open (SeleniumOnRails::TestBuilderActions)
- open_window (SeleniumOnRails::TestBuilderActions)
- pause (SeleniumOnRails::TestBuilderActions)
- record (SeleniumController)
- refresh (SeleniumOnRails::TestBuilderActions)
- remove_all_selections (SeleniumOnRails::TestBuilderActions)
- remove_selection (SeleniumOnRails::TestBuilderActions)
- render (SeleniumOnRails::RSelenese)
- render (SeleniumOnRails::Selenese)
- render_partial (SeleniumOnRails::PartialsSupport)
- render_test_case (SeleniumOnRails::Renderer)
- select (SeleniumOnRails::TestBuilderActions)
- select_frame (SeleniumOnRails::TestBuilderActions)
- select_window (SeleniumOnRails::TestBuilderActions)
- selenium_path (SeleniumOnRails::Paths)
- selenium_tests_path (SeleniumOnRails::Paths)
- selenize (SeleniumOnRails::TestBuilder)
- set_context (SeleniumOnRails::TestBuilderActions)
- set_cursor_position (SeleniumOnRails::TestBuilderActions)
- set_mouse_speed (SeleniumOnRails::TestBuilderActions)
- set_timeout (SeleniumOnRails::TestBuilderActions)
- setup (SeleniumOnRails::TestBuilderActions)
- setup (SeleniumController)
- shift_key_down (SeleniumOnRails::TestBuilderActions)
- shift_key_up (SeleniumOnRails::TestBuilderActions)
- skip_file? (SeleniumOnRails::Paths)
- store (SeleniumOnRails::TestBuilderActions)
- store_absolute_location (SeleniumOnRails::TestBuilderAccessors)
- store_alert (SeleniumOnRails::TestBuilderAccessors)
- store_alert_present (SeleniumOnRails::TestBuilderAccessors)
- store_all_buttons (SeleniumOnRails::TestBuilderAccessors)
- store_all_fields (SeleniumOnRails::TestBuilderAccessors)
- store_all_links (SeleniumOnRails::TestBuilderAccessors)
- store_all_window_ids (SeleniumOnRails::TestBuilderAccessors)
- store_all_window_names (SeleniumOnRails::TestBuilderAccessors)
- store_all_window_titles (SeleniumOnRails::TestBuilderAccessors)
- store_attribute (SeleniumOnRails::TestBuilderAccessors)
- store_attribute_from_all_windows (SeleniumOnRails::TestBuilderAccessors)
- store_body_text (SeleniumOnRails::TestBuilderAccessors)
- store_checked (SeleniumOnRails::TestBuilderAccessors)
- store_confirmation (SeleniumOnRails::TestBuilderAccessors)
- store_confirmation_present (SeleniumOnRails::TestBuilderAccessors)
- store_cookie (SeleniumOnRails::TestBuilderAccessors)
- store_cursor_position (SeleniumOnRails::TestBuilderAccessors)
- store_editable (SeleniumOnRails::TestBuilderAccessors)
- store_element_height (SeleniumOnRails::TestBuilderAccessors)
- store_element_index (SeleniumOnRails::TestBuilderAccessors)
- store_element_position_left (SeleniumOnRails::TestBuilderAccessors)
- store_element_position_top (SeleniumOnRails::TestBuilderAccessors)
- store_element_present (SeleniumOnRails::TestBuilderAccessors)
- store_element_width (SeleniumOnRails::TestBuilderAccessors)
- store_error_on_next (SeleniumOnRails::TestBuilderAccessors)
- store_eval (SeleniumOnRails::TestBuilderAccessors)
- store_expression (SeleniumOnRails::TestBuilderAccessors)
- store_failure_on_next (SeleniumOnRails::TestBuilderAccessors)
- store_html_source (SeleniumOnRails::TestBuilderAccessors)
- store_location (SeleniumOnRails::TestBuilderAccessors)
- store_log_messages (SeleniumOnRails::TestBuilderAccessors)
- store_mouse_speed (SeleniumOnRails::TestBuilderAccessors)
- store_ordered (SeleniumOnRails::TestBuilderAccessors)
- store_prompt (SeleniumOnRails::TestBuilderAccessors)
- store_prompt_present (SeleniumOnRails::TestBuilderAccessors)
- store_select_options (SeleniumOnRails::TestBuilderAccessors)
- store_selected (SeleniumOnRails::TestBuilderAccessors)
- store_selected_id (SeleniumOnRails::TestBuilderAccessors)
- store_selected_ids (SeleniumOnRails::TestBuilderAccessors)
- store_selected_index (SeleniumOnRails::TestBuilderAccessors)
- store_selected_indexes (SeleniumOnRails::TestBuilderAccessors)
- store_selected_label (SeleniumOnRails::TestBuilderAccessors)
- store_selected_labels (SeleniumOnRails::TestBuilderAccessors)
- store_selected_options (SeleniumOnRails::TestBuilderAccessors)
- store_selected_value (SeleniumOnRails::TestBuilderAccessors)
- store_selected_values (SeleniumOnRails::TestBuilderAccessors)
- store_something_selected (SeleniumOnRails::TestBuilderAccessors)
- store_table (SeleniumOnRails::TestBuilderAccessors)
- store_text (SeleniumOnRails::TestBuilderAccessors)
- store_text_present (SeleniumOnRails::TestBuilderAccessors)
- store_title (SeleniumOnRails::TestBuilderAccessors)
- store_value (SeleniumOnRails::TestBuilderAccessors)
- store_visible (SeleniumOnRails::TestBuilderAccessors)
- store_whether_this_frame_match_frame_expression (SeleniumOnRails::TestBuilderAccessors)
- store_whether_this_window_match_window_expression (SeleniumOnRails::TestBuilderAccessors)
- submit (SeleniumOnRails::TestBuilderActions)
- support_file (SeleniumController)
- table (SeleniumOnRails::TestBuilder)
- test_case_name (SeleniumHelper)
- test_cases (SeleniumOnRails::SuiteRenderer)
- test_file (SeleniumController)
- test_suite_name (SeleniumOnRails::SuiteRenderer)
- test_suites (SeleniumOnRails::SuiteRenderer)
- type (SeleniumOnRails::TestBuilderActions)
- type_keys (SeleniumOnRails::TestBuilderActions)
- uncheck (SeleniumOnRails::TestBuilderActions)
- url_arg (SeleniumOnRails::TestBuilder)
- view_path (SeleniumOnRails::Paths)
- wait_for_condition (SeleniumOnRails::TestBuilderActions)
- wait_for_page_to_load (SeleniumOnRails::TestBuilderActions)
- wait_for_popup (SeleniumOnRails::TestBuilderActions)
- window_focus (SeleniumOnRails::TestBuilderActions)
- window_maximize (SeleniumOnRails::TestBuilderActions)
-
-
- - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/index.html b/vendor/plugins/selenium-on-rails/doc/index.html deleted file mode 100644 index 4baa4f94..00000000 --- a/vendor/plugins/selenium-on-rails/doc/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - SeleniumOnRails - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/doc/rdoc-style.css b/vendor/plugins/selenium-on-rails/doc/rdoc-style.css deleted file mode 100644 index 44c7b3d1..00000000 --- a/vendor/plugins/selenium-on-rails/doc/rdoc-style.css +++ /dev/null @@ -1,208 +0,0 @@ - -body { - font-family: Verdana,Arial,Helvetica,sans-serif; - font-size: 90%; - margin: 0; - margin-left: 40px; - padding: 0; - background: white; -} - -h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; } -h1 { font-size: 150%; } -h2,h3,h4 { margin-top: 1em; } - -a { background: #eef; color: #039; text-decoration: none; } -a:hover { background: #039; color: #eef; } - -/* Override the base stylesheet's Anchor inside a table cell */ -td > a { - background: transparent; - color: #039; - text-decoration: none; -} - -/* and inside a section title */ -.section-title > a { - background: transparent; - color: #eee; - text-decoration: none; -} - -/* === Structural elements =================================== */ - -div#index { - margin: 0; - margin-left: -40px; - padding: 0; - font-size: 90%; -} - - -div#index a { - margin-left: 0.7em; -} - -div#index .section-bar { - margin-left: 0px; - padding-left: 0.7em; - background: #ccc; - font-size: small; -} - - -div#classHeader, div#fileHeader { - width: auto; - color: white; - padding: 0.5em 1.5em 0.5em 1.5em; - margin: 0; - margin-left: -40px; - border-bottom: 3px solid #006; -} - -div#classHeader a, div#fileHeader a { - background: inherit; - color: white; -} - -div#classHeader td, div#fileHeader td { - background: inherit; - color: white; -} - - -div#fileHeader { - background: #057; -} - -div#classHeader { - background: #048; -} - - -.class-name-in-header { - font-size: 180%; - font-weight: bold; -} - - -div#bodyContent { - padding: 0 1.5em 0 1.5em; -} - -div#description { - padding: 0.5em 1.5em; - background: #efefef; - border: 1px dotted #999; -} - -div#description h1,h2,h3,h4,h5,h6 { - color: #125;; - background: transparent; -} - -div#validator-badges { - text-align: center; -} -div#validator-badges img { border: 0; } - -div#copyright { - color: #333; - background: #efefef; - font: 0.75em sans-serif; - margin-top: 5em; - margin-bottom: 0; - padding: 0.5em 2em; -} - - -/* === Classes =================================== */ - -table.header-table { - color: white; - font-size: small; -} - -.type-note { - font-size: small; - color: #DEDEDE; -} - -.xxsection-bar { - background: #eee; - color: #333; - padding: 3px; -} - -.section-bar { - color: #333; - border-bottom: 1px solid #999; - margin-left: -20px; -} - - -.section-title { - background: #79a; - color: #eee; - padding: 3px; - margin-top: 2em; - margin-left: -30px; - border: 1px solid #999; -} - -.top-aligned-row { vertical-align: top } -.bottom-aligned-row { vertical-align: bottom } - -/* --- Context section classes ----------------------- */ - -.context-row { } -.context-item-name { font-family: monospace; font-weight: bold; color: black; } -.context-item-value { font-size: small; color: #448; } -.context-item-desc { color: #333; padding-left: 2em; } - -/* --- Method classes -------------------------- */ -.method-detail { - background: #efefef; - padding: 0; - margin-top: 0.5em; - margin-bottom: 1em; - border: 1px dotted #ccc; -} -.method-heading { - color: black; - background: #ccc; - border-bottom: 1px solid #666; - padding: 0.2em 0.5em 0 0.5em; -} -.method-signature { color: black; background: inherit; } -.method-name { font-weight: bold; } -.method-args { font-style: italic; } -.method-description { padding: 0 0.5em 0 0.5em; } - -/* --- Source code sections -------------------- */ - -a.source-toggle { font-size: 90%; } -div.method-source-code { - background: #262626; - color: #ffdead; - margin: 1em; - padding: 0.5em; - border: 1px dashed #999; - overflow: hidden; -} - -div.method-source-code pre { color: #ffdead; overflow: hidden; } - -/* --- Ruby keyword styles --------------------- */ - -.standalone-code { background: #221111; color: #ffdead; overflow: hidden; } - -.ruby-constant { color: #7fffd4; background: transparent; } -.ruby-keyword { color: #00ffff; background: transparent; } -.ruby-ivar { color: #eedd82; background: transparent; } -.ruby-operator { color: #00ffee; background: transparent; } -.ruby-identifier { color: #ffdead; background: transparent; } -.ruby-node { color: #ffa07a; background: transparent; } -.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } -.ruby-regexp { color: #ffa07a; background: transparent; } -.ruby-value { color: #7fffd4; background: transparent; } \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/generators/selenium/USAGE b/vendor/plugins/selenium-on-rails/generators/selenium/USAGE deleted file mode 100644 index 1a6ae9f0..00000000 --- a/vendor/plugins/selenium-on-rails/generators/selenium/USAGE +++ /dev/null @@ -1,19 +0,0 @@ -Description: - Generates a stub Selenium test case. - -Examples: - ./script/generate selenium login - will create: - /test/selenium/login.sel - - ./script/generate selenium user/create - will create: - /test/selenium/user/create.sel - - ./script/generate selenium login.rsel - will create: - /test/selenium/login.rsel - - ./script/generate selenium logout.rhtml - will create: - /test/selenium/logout.rhtml diff --git a/vendor/plugins/selenium-on-rails/generators/selenium/selenium_generator.rb b/vendor/plugins/selenium-on-rails/generators/selenium/selenium_generator.rb deleted file mode 100644 index bc51ef5a..00000000 --- a/vendor/plugins/selenium-on-rails/generators/selenium/selenium_generator.rb +++ /dev/null @@ -1,50 +0,0 @@ -class SeleniumGenerator < Rails::Generator::Base - def initialize runtime_args, runtime_options = {} - super - usage if @args.empty? - end - - def banner - "Usage: #{$0} #{spec.name} testname [options]" - end - - def manifest - record do |m| - path = 'test/selenium' - path = File.join(path, suite_path) unless suite_path.empty? - m.directory path - - template = case File.extname(filename) - when '.rhtml' then 'rhtml.rhtml' - when '.rsel' then 'rselenese.rhtml' - else 'selenese.rhtml' - end - m.template template, File.join(path, filename) - end - end - - def filename - name = File.basename args[0] - extensions = ['.sel', '.rhtml', '.rsel'] - name = "#{name}.sel" unless extensions.include? File.extname(name) - name - end - - def suite_path - sp = File.dirname args[0] - sp = '' if sp == '.' - sp - end - - def testcase_link - l = "http://localhost:3000/selenium/tests/" - l = "#{l}#{suite_path}/" unless suite_path.empty? - l + filename - end - - def suite_link - l = "http://localhost:3000/selenium" - l = "#{l}/TestRunner.html?test=tests/#{suite_path}" unless suite_path.empty? - l - end -end diff --git a/vendor/plugins/selenium-on-rails/generators/selenium/templates/rhtml.rhtml b/vendor/plugins/selenium-on-rails/generators/selenium/templates/rhtml.rhtml deleted file mode 100644 index c6c4c441..00000000 --- a/vendor/plugins/selenium-on-rails/generators/selenium/templates/rhtml.rhtml +++ /dev/null @@ -1,16 +0,0 @@ -

It's often a good idea to start the test with opening /selenium/setup (see <%%= link_to 'here', :controller => 'selenium', :action => 'setup' %> for more info).

- - - - -<%% for page in ['/', '/home'] -%> - - -<%% end -%> -
<%%= @page_title %>
open/selenium/setup 
open<%%= page %> 
assertTitleHome 
- -

More information about the commands is available here.

- -

You can write comments above and below the commands, but you can only have one set of commands, i.e. one table, per test.

- -

Point the browser to <%= testcase_link %> to see how this test is rendered, or to <%= suite_link %> to run the suite.

diff --git a/vendor/plugins/selenium-on-rails/generators/selenium/templates/rselenese.rhtml b/vendor/plugins/selenium-on-rails/generators/selenium/templates/rselenese.rhtml deleted file mode 100644 index 419eb368..00000000 --- a/vendor/plugins/selenium-on-rails/generators/selenium/templates/rselenese.rhtml +++ /dev/null @@ -1,14 +0,0 @@ -# It's often a good idea to start the test with 'setup'. -# See /selenium/setup for more info. - -setup -open '/' -assert_title 'Home' - -# More information about the commands is available at: -# http://release.openqa.org/selenium-core/nightly/reference.html -# See also the RDoc for SeleniumOnRails::TestBuilder. -# -# Point the browser to <%= testcase_link %> to see -# how this test is rendered, or to <%= suite_link %> to -# run the suite. diff --git a/vendor/plugins/selenium-on-rails/generators/selenium/templates/selenese.rhtml b/vendor/plugins/selenium-on-rails/generators/selenium/templates/selenese.rhtml deleted file mode 100644 index f4ccb8a9..00000000 --- a/vendor/plugins/selenium-on-rails/generators/selenium/templates/selenese.rhtml +++ /dev/null @@ -1,11 +0,0 @@ -It's often a good idea to start the test with opening /selenium/setup (see "here":/selenium/setup for more info). - -|open|/selenium/setup| -|open|/| -|assertTitle|Home| - -More information about the commands is available "here":http://release.openqa.org/selenium-core/nightly/reference.html. - -You can write comments above and below the commands, but you can only have one set of commands, i.e. one table, per test. "RedCloth":http://www.whytheluckystiff.net/ruby/redcloth/ is used for formatting if installed. - -Point the browser to "<%= testcase_link %>":<%= testcase_link %> to see how this test is rendered, or to "<%= suite_link %>":<%= suite_link %> to run the suite. diff --git a/vendor/plugins/selenium-on-rails/init.rb b/vendor/plugins/selenium-on-rails/init.rb deleted file mode 100644 index 185b5847..00000000 --- a/vendor/plugins/selenium-on-rails/init.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'selenium_on_rails_config' -envs = SeleniumOnRailsConfig.get :environments - -if envs.include? RAILS_ENV - #initialize the plugin - $LOAD_PATH << File.dirname(__FILE__) + "/lib/controllers" - require 'selenium_controller' - require File.dirname(__FILE__) + '/routes' - - SeleniumController.prepend_view_path File.expand_path(File.dirname(__FILE__) + '/lib/views') -else - #erase all traces - $LOAD_PATH.delete lib_path -end - diff --git a/vendor/plugins/selenium-on-rails/lib/controllers/selenium_controller.rb b/vendor/plugins/selenium-on-rails/lib/controllers/selenium_controller.rb deleted file mode 100644 index 02e3df8b..00000000 --- a/vendor/plugins/selenium-on-rails/lib/controllers/selenium_controller.rb +++ /dev/null @@ -1,122 +0,0 @@ -require 'webrick/httputils' - -class SeleniumController < ActionController::Base - include SeleniumOnRails::FixtureLoader - include SeleniumOnRails::Renderer - - def initialize - @result_dir = SeleniumOnRailsConfig.get(:result_dir) - end - - def setup - unless params.has_key? :keep_session - reset_session # IS THIS WORKING! NO THINK SO - @session_wiped = true - end - @cleared_tables = clear_tables params[:clear_tables].to_s - @loaded_fixtures = load_fixtures params[:fixtures].to_s - render :file => view_path('setup.rhtml'), :layout => layout_path\ - end - - def test_file - params[:testname] = '' if params[:testname].to_s == 'TestSuite.html' - filename = File.join selenium_tests_path, params[:testname] - if File.directory? filename - @suite_path = filename - render :file => view_path('test_suite.rhtml'), :layout => layout_path - elsif File.readable? filename - render_test_case filename - else - if File.directory? selenium_tests_path - render :text => 'Not found', :status => 404 - else - render :text => "Did not find the Selenium tests path (#{selenium_tests_path}). Run script/generate selenium", :status => 404 - end - end - end - - def support_file - if params[:filename].empty? - redirect_to :filename => 'TestRunner.html', :test => 'tests' - return - end - - filename = File.join selenium_path, params[:filename] - if File.file? filename - type = WEBrick::HTTPUtils::DefaultMimeTypes[$1.downcase] if filename =~ /\.(\w+)$/ - type ||= 'text/html' - send_file filename, :type => type, :disposition => 'inline', :stream => false - else - render :text => 'Not found', :status => 404 - end - end - - def record - dir = record_table - - @result = {'resultDir' => dir} - ['result', 'numTestFailures', 'numTestPasses', 'numCommandFailures', 'numCommandPasses', 'numCommandErrors', 'totalTime'].each do |item| - @result[item] = params[item] - end - - File.open(log_path(params[:logFile] || 'default.yml'), 'w') {|f| YAML.dump(@result, f)} - - render :file => view_path('record.rhtml'), :layout => layout_path - end - - def record_table - return nil unless @result_dir - - cur_result_dir = File.join(@result_dir, (params[:logFile] || "default").sub(/\.yml$/, '')) - FileUtils.mkdir_p(cur_result_dir) - File.open("#{cur_result_dir}/index.html", "wb") do |f| - f.write < -Selenium Test Result - - - - - -EOS - end - html_header = < - - - - -EOS - html_footer = "\n" - if selenium_path - css_file = File.join selenium_path, "selenium-test.css" - if File.exist?(css_file) - FileUtils.cp css_file, cur_result_dir - end - end - File.open("#{cur_result_dir}/blank.html", "wb") do |f| - f.write "" - end - File.open("#{cur_result_dir}/suite.html", "wb") do |f| - suite = params[:suite] - suite.sub!(/^.*(])/im, '\1') - i = 1 - suite.gsub!(/(\shref=)"[^"]*"/i) do |m| - link = "#{$1}\"test#{i}.html\" target=\"testcase\"" - File.open("#{cur_result_dir}/test#{i}.html", "wb") do |testcase| - testcase.write html_header - testcase.write(params["testTable.#{i}"]) - testcase.write html_footer - end - i += 1 - link - end - f.write html_header - f.write suite - f.write html_footer - end - cur_result_dir - end - - private :record_table -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/controllers/switch_environment_controller.rb b/vendor/plugins/selenium-on-rails/lib/controllers/switch_environment_controller.rb deleted file mode 100644 index 67e8ae50..00000000 --- a/vendor/plugins/selenium-on-rails/lib/controllers/switch_environment_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -class SwitchEnvironmentController < ActionController::Base - def index - readme_path = File.expand_path File.join(File.dirname(__FILE__), '..', 'README') - render :status => 500, :locals => {:readme_path => readme_path }, :inline => < - Selenium on Rails is only activated for <%= SeleniumOnRailsConfig.get(:environments).join ', ' %> - environment<%= SeleniumOnRailsConfig.get(:environments).size > 1 ? 's' : '' %> (you're running - <%= RAILS_ENV %>). -

-

- Start your server in a different environment or see <%= readme_path %> - for information regarding how to change this behavior. -

-END - end -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_helper.rb b/vendor/plugins/selenium-on-rails/lib/selenium_helper.rb deleted file mode 100644 index f3b1f3c7..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_helper.rb +++ /dev/null @@ -1,8 +0,0 @@ -module SeleniumHelper - include SeleniumOnRails::SuiteRenderer - include SeleniumOnRails::FixtureLoader - - def test_case_name filename - File.basename(filename).sub(/\..*/,'').humanize - end -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails.rb deleted file mode 100644 index 365d0034..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails.rb +++ /dev/null @@ -1,11 +0,0 @@ -module SeleniumOnRails # :nodoc -end - -require 'selenium_on_rails/selenese' -require 'selenium_on_rails/test_builder' -require 'selenium_on_rails/rselenese' -require 'selenium_on_rails/suite_renderer' -require 'selenium_on_rails/paths' -require 'selenium_on_rails/fixture_loader' -require 'selenium_on_rails/partials_support' -require 'selenium_on_rails/renderer' diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/acceptance_test_runner.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/acceptance_test_runner.rb deleted file mode 100644 index 69afffda..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/acceptance_test_runner.rb +++ /dev/null @@ -1,214 +0,0 @@ -$: << File.expand_path(File.dirname(__FILE__) + "/") -$: << File.expand_path(File.dirname(__FILE__) + "/../") -require 'paths' -require 'net/http' -require 'tempfile' - - -def c(var, default = nil) SeleniumOnRailsConfig.get var, default end -def c_b(var, default = nil) SeleniumOnRailsConfig.get(var, default) { yield } end - -BROWSERS = c :browsers, {} -REUSE_EXISTING_SERVER = c :reuse_existing_server, true -START_SERVER = c :start_server, false #TODO can't get it to work reliably on Windows, perhaps it's just on my computer, but I leave it off by default for now -HOST = c :host, 'localhost' -PORTS = c(:port_start, 3000)..c(:port_end, 3005) -BASE_URL_PATH = c :base_url_path, '/' -TEST_RUNNER_URL = c :test_runner_url, '/selenium/TestRunner.html' -MAX_BROWSER_DURATION = c :max_browser_duration, 2*60 -MULTI_WINDOW = c :multi_window, false -SERVER_COMMAND = c_b :server_command do - server_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../script/server') - if RUBY_PLATFORM =~ /mswin/ - "ruby #{server_path} webrick -p %d -e test > NUL 2>&1" - else - # don't use redirects to /dev/nul since it makes the fork return wrong pid - # see UnixSubProcess - "#{server_path} webrick -p %d -e test" - end -end - -module SeleniumOnRails - class AcceptanceTestRunner - include SeleniumOnRails::Paths - - def run - raise 'no browser specified, edit/create config.yml' if BROWSERS.empty? - start_server - has_error = false - begin - BROWSERS.each_pair do |browser, path| - log_file = start_browser browser, path - wait_for_completion log_file - stop_browser - result = YAML::load_file log_file - print_result result - has_error ||= result['numTestFailures'].to_i > 0 - # File.delete log_file unless has_error - end - rescue - stop_server - raise - end - stop_server - raise 'Test failures' if has_error - end - - private - def start_server - PORTS.each do |p| - @port = p - case server_check - when :success - return if REUSE_EXISTING_SERVER - next - when Fixnum - next - when :no_response - next unless START_SERVER - do_start_server - return - end - end - raise START_SERVER ? 'failed to start server': 'failed to find existing server, run script/server -e test' - end - - def do_start_server - puts 'Starting server' - @server = start_subprocess(format(SERVER_COMMAND, @port)) - while true - print '.' - r = server_check - if r == :success - puts - return - end - raise "server returned error: #{r}" if r.instance_of? Fixnum - sleep 3 - end - end - - def server_check - begin - res = Net::HTTP.get_response HOST, TEST_RUNNER_URL, @port - return :success if (200..399).include? res.code.to_i - return res.code.to_i - rescue Errno::ECONNREFUSED - return :no_response - end - end - - def stop_server - return unless defined? @server - puts - @server.stop 'server' - end - - def start_browser browser, path - puts - puts "Starting #{browser}" - base_url = "http://#{HOST}:#{@port}#{BASE_URL_PATH}" - log = log_file browser - command = "\"#{path}\" \"http://#{HOST}:#{@port}#{TEST_RUNNER_URL}?test=tests&auto=true&baseUrl=#{base_url}&resultsUrl=postResults/#{log}&multiWindow=#{MULTI_WINDOW}\"" - @browser = start_subprocess command - log_path log - end - - def stop_browser - @browser.stop 'browser' - end - - def start_subprocess command - if RUBY_PLATFORM =~ /mswin/ - SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess.new command - elsif RUBY_PLATFORM =~ /darwin/i && command =~ /safari/i - SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess.new command - else - SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess.new command - end - end - - def log_file browser - FileUtils.mkdir_p(log_path('')) - (0..100).each do |i| - name = browser + (i==0 ? '' : "(#{i})") + '.yml' - return name unless File.exist?(log_path(name)) - end - raise 'there are way too many files in the log directory...' - end - - def wait_for_completion log_file - duration = 0 - while true - raise 'browser takes too long' if duration > MAX_BROWSER_DURATION - print '.' - break if File.exist? log_file - sleep 5 - duration += 5 - end - puts - end - - def print_result result - puts "Finished in #{result['totalTime']} seconds." - puts - puts "#{result['numTestPasses']} tests passed, #{result['numTestFailures']} tests failed" - puts "(Results stored in '#{result['resultDir']}')" if result['resultDir'] - end - - end -end - -class SeleniumOnRails::AcceptanceTestRunner::SubProcess - def stop what - begin - puts "Stopping #{what} (pid=#{@pid}) ..." - Process.kill 9, @pid - rescue Errno::EPERM #such as the process is already closed (tabbed browser) - end - end -end - -class SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess - def initialize command - require 'win32/open3' #win32-open3 http://raa.ruby-lang.org/project/win32-open3/ - - puts command - input, output, error, @pid = Open4.popen4 command, 't', true - end -end - -class SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess - def initialize command - puts command - @pid = fork do - # Since we can't use shell redirects without screwing - # up the pid, we'll reopen stdin and stdout instead - # to get the same effect. - [STDOUT,STDERR].each {|f| f.reopen '/dev/null', 'w' } - exec command - end - end -end - -# The path to Safari should look like this: /Applications/Safari.app/Contents/MacOS/Safari -class SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess < SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess - def initialize command - f = File.open(Tempfile.new('selenium-on-rails').path, 'w') - f.puts <<-HTML - - - - - - - HTML - f.close - - super "#{command.split.first} #{f.path}" - end - -end - diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/fixture_loader.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/fixture_loader.rb deleted file mode 100644 index 77cd6203..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/fixture_loader.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'test/unit' -require 'active_record' -require 'active_record/fixtures' - -module SeleniumOnRails::FixtureLoader - include SeleniumOnRails::Paths - - def available_fixtures - fixtures = {} - path = fixtures_path + '/' - files = Dir["#{path}**/*.{yml,csv}"] - files.each do |file| - rel_path = file.sub(path, '') - next if skip_file? rel_path - fixture_set = File.dirname(rel_path) - fixture_set = '' if fixture_set == '.' - fixture = rel_path.sub /\.[^.]*$/, '' - fixtures[fixture_set] ||= [] - fixtures[fixture_set] << fixture - end - - fixtures - end - - def load_fixtures fixtures_param - available = nil - fixtures = fixtures_param.split(/\s*,\s*/).collect do |f| - fixture_set = File.dirname f - fixture_set = '' if fixture_set == '.' - fixture = File.basename f - if fixture == 'all' - available ||= available_fixtures - available[fixture_set] - else - f - end - end - fixtures.flatten! - fixtures.reject! {|f| f.blank? } - - if fixtures.any? - Fixtures.reset_cache # in case they've already been loaded and things have changed - Fixtures.create_fixtures fixtures_path, fixtures - end - fixtures - end - - def clear_tables tables - table_names = tables.split /\s*,\s*/ - connection = ActiveRecord::Base.connection - table_names.each do |table| - connection.execute "DELETE FROM #{table}" - end - table_names - end - -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/partials_support.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/partials_support.rb deleted file mode 100644 index b9d557ef..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/partials_support.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'selenium_on_rails/paths' - -module SeleniumOnRails::PartialsSupport - include SeleniumOnRails::Paths - - # Overrides where the partial is searched for, and returns only the command table rows. - def render_partial(options) - pattern = partial_pattern options[:partial] - filename = Dir[pattern].first - raise "Partial '#{partial_path}' cannot be found! (Looking for file: '#{pattern}')" unless filename - partial = render :file => filename, :use_full_path => false, :locals => options[:locals] - extract_commands_from_partial partial - end - - # Extracts the commands from a partial. The partial must contain a html table - # and the first row is ignored since it cannot contain a command. - def extract_commands_from_partial partial - partial = partial.match(/.*.*?.*?<\/tr>(.*?)<\/table>/im)[1] - raise "Partial '#{name}' doesn't contain any table" unless partial - partial - end - - private - # Generates the file pattern from the provided partial path. - # The starting _ and file extension don't have too be provided. - def partial_pattern partial_path - path = partial_path.split '/' - filename = path.delete_at(-1) - filename = '_' + filename unless filename.starts_with? '_' - filename << '.*' unless filename.include? '.' - pattern = selenium_tests_path + '/' - pattern << path.join('/') + '/' if path - pattern << filename - end - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/paths.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/paths.rb deleted file mode 100644 index 5910ec43..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/paths.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'selenium_on_rails_config' - -module SeleniumOnRails - module Paths - - def selenium_path - @@selenium_path ||= find_selenium_path - @@selenium_path - end - - def selenium_tests_path - return SeleniumOnRailsConfig.get("selenium_tests_path") if SeleniumOnRailsConfig.get("selenium_tests_path") - File.expand_path(File.join(RAILS_ROOT, 'test/selenium')) - end - - def view_path view - File.expand_path(File.dirname(__FILE__) + '/../views/' + view) - end - - # Returns the path to the layout template. The path is relative in relation - # to the app/views/ directory since Rails doesn't support absolute paths - # to layout templates. - def layout_path - 'layout.rhtml' - end - - def fixtures_path - return SeleniumOnRailsConfig.get("fixtures_path") if SeleniumOnRailsConfig.get("fixtures_path") - File.expand_path File.join(RAILS_ROOT, 'test/fixtures') - end - - def log_path log_file - File.expand_path(File.dirname(__FILE__) + '/../../log/' + File.basename(log_file)) - end - - def skip_file? file - file.split('/').each do |f| - return true if f.upcase == 'CVS' or f.starts_with?('.') or f.ends_with?('~') or f.starts_with?('_') - end - false - end - - private ############################################### - - def find_selenium_path - sel_dirs = SeleniumOnRailsConfig.get :selenium_path do - File.expand_path(File.dirname(__FILE__) + '/../../selenium-core') - end - - sel_dirs.to_a.each do |seleniumdir| - ['', 'core', 'selenium', 'javascript'].each do |subdir| - path = File.join seleniumdir, subdir - return path if File.exist?(File.join(path, 'TestRunner.html')) - end - end - - raise 'Could not find Selenium Core installation' - end - - end -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/renderer.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/renderer.rb deleted file mode 100644 index 76b770eb..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/renderer.rb +++ /dev/null @@ -1,20 +0,0 @@ -module SeleniumOnRails::Renderer - include SeleniumOnRails::Paths - - def render_test_case filename - @template.extend SeleniumOnRails::PartialsSupport - @page_title = test_case_name filename - output = render_to_string :file => filename, :locals => {"page_title" => @page_title} - layout = (output =~ //i ? false : layout_path) - render :text => output, :layout => layout - - headers['Cache-control'] = 'no-cache' - headers['Pragma'] = 'no-cache' - headers['Expires'] = '-1' - end - - def test_case_name filename - File.basename(filename).sub(/\..*/,'').humanize - end - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/rselenese.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/rselenese.rb deleted file mode 100644 index cc297f0f..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/rselenese.rb +++ /dev/null @@ -1,44 +0,0 @@ -# Renders Selenium test templates in a fashion analogous to +rxml+ and -# +rjs+ templates. -# -# setup -# open :controller => 'customer', :action => 'list' -# assert_title 'Customers' -# -# See SeleniumOnRails::TestBuilder for a list of available commands. -class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder -end -ActionView::Template.register_template_handler 'rsel', SeleniumOnRails::RSelenese - -class SeleniumOnRails::RSelenese - attr_accessor :view - - def initialize view - super view - @view = view - end - - def render template, local_assigns = {} - title = (@view.assigns['page_title'] or local_assigns['page_title']) - - evaluator = Evaluator.new(@view) - evaluator.run_script title, assign_locals_code_from(local_assigns) + "\n" + template.source, local_assigns - end - - def assign_locals_code_from(local_assigns) - return local_assigns.keys.collect {|key| "#{key} = local_assigns[#{key.inspect}];"}.join - end - - def self.call(template) - "#{name}.new(self).render(template, local_assigns)" - end - - class Evaluator < SeleniumOnRails::TestBuilder - def run_script(title, script, local_assigns) - table(title) do - test = self #to enable test.command - eval script - end - end - end -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/selenese.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/selenese.rb deleted file mode 100644 index d65a8df6..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/selenese.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'selenium_on_rails/partials_support' - -class SeleniumOnRails::Selenese -end -ActionView::Template.register_template_handler 'sel', SeleniumOnRails::Selenese - - -class SeleniumOnRails::Selenese - def initialize view - @view = view - end - - def render template, local_assigns = {} - name = (@view.assigns['page_title'] or local_assigns['page_title']) - lines = template.source.strip.split "\n" - html = '' - html << extract_comments(lines) - html << extract_commands(lines, name) - html << extract_comments(lines) - raise 'You cannot have comments in the middle of commands!' if next_line lines, :any - html - end - - private - def next_line lines, expects - while lines.any? - l = lines.shift.strip - next if (l.empty? and expects != :comment) - comment = (l =~ /^\|.*\|$/).nil? - if (comment and expects == :command) or (!comment and expects == :comment) - lines.unshift l - return nil - end - return l - end - end - - def self.call(template) - "#{name}.new(self).render(template, local_assigns)" - end - - def extract_comments lines - comments = '' - while (line = next_line lines, :comment) - comments << line + "\n" - end - if defined? RedCloth - comments = RedCloth.new(comments).to_html - end - comments += "\n" unless comments.empty? - comments - end - - def extract_commands lines, name - html = "
\n\n" - while (line = next_line lines, :command) - line = line[1..-2] #remove starting and ending | - cells = line.split '|' - if cells.first == 'includePartial' - html << include_partial(cells[1..-1]) - next - end - raise 'There might only be a maximum of three cells!' if cells.length > 3 - html << '' - (1..3).each do - cell = cells.shift - cell = (cell ? CGI.escapeHTML(cell.strip) : ' ') - html << "" - end - html << "\n" - end - html << "
#{name}
#{cell}
\n" - end - - def include_partial params - partial = params.shift - locals = {} - params.each do |assignment| - next if assignment.empty? - _, var, value = assignment.split(/^([a-z_][a-zA-Z0-9_]*)\s*=\s*(.*)$/) - raise "Invalid format '#{assignment}'. Should be '|includePartial|partial|var1=value|var2=value|." unless var - locals[var.to_sym] = value or '' - end - @view.render :partial => partial, :locals => locals - end - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/suite_renderer.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/suite_renderer.rb deleted file mode 100644 index 0774e841..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/suite_renderer.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'selenium_on_rails' - -module SeleniumOnRails - module SuiteRenderer - def test_suite_name path - return 'All test cases' if [nil, '/'].include? path_to_relative_url(path) - File.split(path)[-1].humanize - end - - def test_suites path - suites = [] - - parent_path = File.join(File.split(path).slice(0..-2)) #all but last - parent_path = path_to_relative_url parent_path - suites << ['..', parent_path] unless parent_path.nil? - - visit_all_tests path, '', Proc.new {|n, p| suites << [n,path_to_relative_url(p)]}, nil - suites - end - - def test_cases path - tests = [] - visit_all_tests path, '', nil, Proc.new {|n, p| tests << [n,p]} - tests - end - - def link_to_test_case suite_name, filename - name = suite_name + test_case_name(filename) - link_to name, :action => :test_file, :testname => path_to_relative_url(filename).sub(/^\//,'') - end - - private ############################################### - - def path_to_relative_url path - slt = @controller.selenium_tests_path - return nil unless path.index slt - path.sub slt, '' - end - - def visit_all_tests path, suite_name, suite_consumer, test_consumer - dirs = [] #add dirs to an array in order for files to be processed before dirs - Dir.entries(path).sort.each do |e| - next if skip_file?(e) or ['.','..'].include?(e) - filename = File.join path, e - if File.directory? filename - dirs << [filename, "#{suite_name}#{e.humanize}."] - suite_consumer.call("#{suite_name}#{e.humanize}", filename) if suite_consumer - else - test_consumer.call(suite_name, filename) if test_consumer - end - end - #recurse through dirs - dirs.each {|p, n| visit_all_tests p, n, suite_consumer, test_consumer } - end - end -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder.rb deleted file mode 100644 index 53f7e7aa..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'selenium_on_rails/test_builder_actions' -require 'selenium_on_rails/test_builder_accessors' - -# Create test_builder_user_actions.rb to support actions included -# in selenium-core's user-extensions.js -# -# See test_builder_user_actions.rb.example for examples matching -# selenium-core's user-extensions.js.sample -module SeleniumOnRails::TestBuilderUserActions -end -require 'selenium_on_rails/test_builder_user_actions' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_actions.rb'))) - - -# Create test_builder_user_accessors.rb to support accessors -# included in selenium-core's user-extensions.js -# -# See test_builder_user_accessors.rb.example for examples matching -# selenium-core's user-extensions.js.sample -module SeleniumOnRails::TestBuilderUserAccessors -end -require 'selenium_on_rails/test_builder_user_accessors' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_accessors.rb'))) - -# Builds Selenium test table using a high-level Ruby interface. Normally -# invoked through SeleniumOnRails::RSelenese. -# -# See SeleniumOnRails::TestBuilderActions for the available actions and -# SeleniumOnRails::TestBuilderAccessors for the available checks. -# -# For more information on the commands supported by TestBuilder, see the -# Selenium Commands Documentation at -# http://release.openqa.org/selenium-core/nightly/reference.html. -class SeleniumOnRails::TestBuilder - include SeleniumOnRails::TestBuilderActions - include SeleniumOnRails::TestBuilderAccessors - include SeleniumOnRails::TestBuilderUserActions - include SeleniumOnRails::TestBuilderUserAccessors - - # Convert _str_ to a Selenium command name. - def self.selenize str - str.camelize.gsub(/^[A-Z]/) {|s| s.downcase } - end - - # Prepends _pattern_ with 'exact:' if it would be considered containing - # string-match pattern otherwise. - def exactize pattern - pattern.include?(':') ? "exact:#{pattern}" : pattern - end - - # Create a new TestBuilder for _view_. - def initialize view - @view = view - @output = '' - @xml = Builder::XmlMarkup.new :indent => 2, :target => @output - end - - # Add a new table of tests, and return the HTML. - def table title - @xml.table do - @xml.tr do @xml.th(title, :colspan => 3) end - yield self - end - end - - # Add a new test command using _cmd_, _target_ and _value_. - def command cmd, target=nil, value=nil - @xml.tr do - _tdata cmd - _tdata target - _tdata value - end - end - # :nodoc - alias_method :command_verbatim, :command - - # Same as _command_ but add _AndWait_ to the name of _cmd_. - def command_and_wait cmd, target=nil, value=nil - command_verbatim cmd.to_s + 'AndWait', target, value - end - - # Re routes commands in the provided block to #command_and_wait instead of - # #command. - def make_command_waiting - self.class.send :alias_method, :command, :command_and_wait - yield - self.class.send :alias_method, :command, :command_verbatim - end - -protected - - # If _url_ is a string, return unchanged. Otherwise, pass it to - # ActionView#UrlHelper#url_for. - def url_arg url - if url.instance_of?(String) then url else exactize(@view.url_for(url)) end - end - - # If _arg_ is an array formats _arg_ to a textual representation. - # Otherwise return unchanged. - def collection_arg arg - if arg.is_a? Array - arg.collect {|e| e.gsub(/[\\,]/) {|s| "\\#{s}" } }.join(',') - else - arg - end - end - -private - - # Output a single TD element. - def _tdata value - if value - @xml.td(value.to_s) - else - @xml.td do @xml.target! << ' ' end - end - end -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_accessors.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_accessors.rb deleted file mode 100644 index ccd09fb3..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_accessors.rb +++ /dev/null @@ -1,1002 +0,0 @@ -# The accessors available for SeleniumOnRails::TestBuilder tests. -# -# For each +store_foo+ there's +assert_foo+, +assert_not_foo+, +verify_foo+, -# +verify_not_foo+, +wait_for_foo+, +wait_for_not_foo+. -module SeleniumOnRails::TestBuilderAccessors - - # Tell Selenium to expect an error on the next command execution. - # - # NOTE: store_error_on_next is currently not supported by - # Selenium Core and is only added to here as a shortcut for - # generating the related assertions. - # - # Related Assertions, automatically generated: - # * assert_error_on_next(message) - # * assert_not_error_on_next(message) - # * verify_error_on_next(message) - # * verify_not_error_on_next(message) - # * wait_for_error_on_next(message) - # * wait_for_not_error_on_next(message) - def store_error_on_next message - raise 'Not supported in Selenium Core at the moment' - end - - # Tell Selenium to expect a failure on the next command execution. - # - # NOTE: store_failure_on_next is currently not supported by - # Selenium Core and is only added to here as a shortcut for - # generating the related assertions. - # - # Related Assertions, automatically generated: - # * assert_failure_on_next(message) - # * assert_not_failure_on_next(message) - # * verify_failure_on_next(message) - # * verify_not_failure_on_next(message) - # * wait_for_failure_on_next(message) - # * wait_for_not_failure_on_next(message) - def store_failure_on_next message - raise 'Not supported in Selenium Core at the moment' - end - - # Returns the IDs of all windows that the browser knows about. - # - # Related Assertions, automatically generated: - # * assertAllWindowIds(pattern) - # * assertNotAllWindowIds(pattern) - # * verifyAllWindowIds(pattern) - # * verifyNotAllWindowIds(pattern) - # * waitForAllWindowIds(pattern) - # * waitForNotAllWindowIds(pattern) - def store_all_window_ids variable_name - command 'storeAllWindowIds', variable_name - end - - # Returns the names of all windows that the browser knows about. - # - # Related Assertions, automatically generated: - # * assertAllWindowNames(pattern) - # * assertNotAllWindowNames(pattern) - # * verifyAllWindowNames(pattern) - # * verifyNotAllWindowNames(pattern) - # * waitForAllWindowNames(pattern) - # * waitForNotAllWindowNames(pattern) - def store_all_window_names variable_name - command 'storeAllWindowNames', variable_name - end - - # Returns the titles of all windows that the browser knows about. - # - # Related Assertions, automatically generated: - # * assertAllWindowTitles(pattern) - # * assertNotAllWindowTitles(pattern) - # * verifyAllWindowTitles(pattern) - # * verifyNotAllWindowTitles(pattern) - # * waitForAllWindowTitles(pattern) - # * waitForNotAllWindowTitles(pattern) - def store_all_window_titles variable_name - command 'storeAllWindowTitles', variable_name - end - - # Has an alert occurred? - # - # Related Assertions, automatically generated: - # * assert_alert_present - # * assert_alert_not_present - # * verify_alert_present - # * verify_alert_not_present - # * wait_for_alert_present - # * wait_for_alert_not_present - def store_alert_present variable_name - command 'storeAlertPresent', variable_name - end - - # Returns every instance of some attribute from all known windows. - # - # Related Assertions, automatically generated: - # * assert_attribute_from_all_windows(attribute_name, pattern) - # * assert_not_attribute_from_all_windows(attribute_name, pattern) - # * verify_attribute_from_all_windows(attribute_name, pattern) - # * verify_not_attribute_from_all_windows(attribute_name, pattern) - # * wait_for_attribute_from_all_windows(attribute_name, pattern) - # * wait_for_not_attribute_from_all_windows(attribute_name, pattern) - def store_attribute_from_all_windows attribute_name, variable_name - command 'storeAttributeFromAllWindows', attribute_name, variable_name - end - - # Has a prompt occurred? - # - # Related Assertions, automatically generated: - # * assert_prompt_present - # * assert_prompt_not_present - # * verify_prompt_present - # * verify_prompt_not_present - # * wait_for_prompt_present - # * wait_for_prompt_not_present - def store_prompt_present variable_name - command 'storePromptPresent', variable_name - end - - # Has confirm() been called? - # - # Related Assertions, automatically generated: - # * assert_confirmation_present - # * assert_confirmation_not_present - # * verify_confirmation_present - # * verify_confirmation_not_present - # * wait_for_confirmation_present - # * wait_for_confirmation_not_present - def store_confirmation_present variable_name - command 'storeConfirmationPresent', variable_name - end - - # Return all cookies of the current page under test. - # - # Related Assertions, automatically generated: - # * assert_cookie(pattern) - # * assert_not_cookie(pattern) - # * verify_cookie(pattern) - # * verify_not_cookie(pattern) - # * wait_for_cookie(pattern) - # * wait_for_not_cookie(pattern) - def store_cookie variable_name - command 'storeCookie', variable_name - end - - # Retrieves the text cursor position in the given input element or - # textarea; beware, this may not work perfectly on all browsers. - # - # This method will fail if the specified element isn't an input element - # or textarea, or there is no cursor in the element. - # - # Related Assertions, automatically generated: - # * assert_cursor_position(locator, pattern) - # * assert_not_cursor_position(locator, pattern) - # * verify_cursor_position(locator, pattern) - # * verify_not_cursor_position(locator, pattern) - # * wait_for_cursor_position(locator, pattern) - # * wait_for_not_cursor_position(locator, pattern) - def store_cursor_position locator, variable_name - command 'storeCursorPosition', locator, variable_name - end - - # Retrieves the message of a JavaScript alert generated during the previous - # action, or fail if there were no alerts. - # - # Getting an alert has the same effect as manually clicking OK. If an alert - # is generated but you do not get/verify it, the next Selenium action will - # fail. - # - # NOTE: under Selenium, JavaScript alerts will NOT pop up a visible alert - # dialog. - # - # NOTE: Selenium does NOT support JavaScript alerts that are generated in a - # page's onload() event handler. In this case a visible dialog WILL be - # generated and Selenium will hang until someone manually clicks OK. - # - # Related Assertions, automatically generated: - # * assert_alert(pattern) - # * assert_not_alert(pattern) - # * verify_alert_present(pattern) - # * verify_not_alert(pattern) - # * wait_for_alert(pattern) - # * wait_for_not_alert(pattern) - def store_alert variable_name - command 'storeAlert', variable_name - end - - # Retrieves the message of a JavaScript confirmation dialog generated during - # the previous action. - # - # By default, the confirm function will return +true+, having the same effect - # as manually clicking OK. This can be changed by prior execution of the - # +choose_cancel_on_next_confirmation+ command. If a confirmation is - # generated but you do not get/verify it, the next Selenium action will fail. - # - # NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible - # dialog. - # - # NOTE: Selenium does NOT support JavaScript confirmations that are generated - # in a page's onload() event handler. In this case a visible dialog WILL be - # generated and Selenium will hang until you manually click OK. - # - # Related Assertions, automatically generated: - # * assert_confirmation(pattern) - # * assert_not_confirmation(pattern) - # * verify_confirmation_present(pattern) - # * verify_not_confirmation(pattern) - # * wait_for_confirmation(pattern) - # * wait_for_not_confirmation(pattern) - def store_confirmation variable_name - command 'storeConfirmation', variable_name - end - - # Retrieves the message of a JavaScript question prompt dialog generated - # during the previous action. - # - # Successful handling of the prompt requires prior execution of the - # +answer_on_next_prompt+ command. If a prompt is generated but you do not - # get/verify it, the next Selenium action will fail. - # - # NOTE: under Selenium, JavaScript prompts will NOT pop up a visible dialog. - # - # NOTE: Selenium does NOT support JavaScript prompts that are generated in a - # page's onload() event handler. In this case a visible dialog WILL be - # generated and Selenium will hang until someone manually clicks OK. - # - # Related Assertions, automatically generated: - # * assert_prompt(pattern) - # * assert_not_prompt(pattern) - # * verify_prompt_present(pattern) - # * verify_not_prompt(pattern) - # * wait_for_prompt(pattern) - # * wait_for_not_prompt(pattern) - def store_prompt variable_name - command 'storePrompt', variable_name - end - - # Gets the absolute URL of the current page. - # - # Related Assertions, automatically generated: - # * assert_absolute_location(pattern) - # * assert_not_absolute_location(pattern) - # * verify_absolute_location_present(pattern) - # * verify_not_absolute_location(pattern) - # * wait_for_absolute_location(pattern) - # * wait_for_not_absolute_location(pattern) - def store_absolute_location variable_name - command 'storeAbsoluteLocation', variable_name - end - - # Verify the location of the current page ends with the expected location. - # If an URL querystring is provided, this is checked as well. - # - # Related Assertions, automatically generated: - # * assert_location(pattern) - # * assert_not_location(pattern) - # * verify_location_present(pattern) - # * verify_not_location(pattern) - # * wait_for_location(pattern) - # * wait_for_not_location(pattern) - def store_location expected_location, variable_name - command 'storeLocation', expected_location, variable_name - end - - # Returns the number of pixels between "mousemove" events during - # drag_and_drop commands (default=10). - # - # Related Assertions, automatically generated: - # * assert_mouse_speed(pattern) - # * assert_not_mouse_speed(pattern) - # * verify_mouse_speed(pattern) - # * verify_not_mouse_speed(pattern) - # * wait_for_mouse_speed(pattern) - # * wait_for_not_mouse_speed(pattern) - def store_mouse_speed variable_name - command 'storeMouseSpeed', variable_name - end - - # Gets the title of the current page. - # - # Related Assertions, automatically generated: - # * assert_title(pattern) - # * assert_not_title(pattern) - # * verify_title_present(pattern) - # * verify_not_title(pattern) - # * wait_for_title(pattern) - # * wait_for_not_title(pattern) - def store_title variable_name - command 'storeTitle', variable_name - end - - # Gets the entire text of the page. - # - # Related Assertions, automatically generated: - # * assert_body_text(pattern) - # * assert_not_body_text(pattern) - # * verify_body_text_present(pattern) - # * verify_not_body_text(pattern) - # * wait_for_body_text(pattern) - # * wait_for_not_body_text(pattern) - def store_body_text variable_name - command 'storeBodyText', variable_name - end - - # Gets the (whitespace-trimmed) value of an input field (or anything else - # with a value parameter). For checkbox/radio elements, the value will be - # "on" or "off" depending on whether the element is checked or not. - # - # Related Assertions, automatically generated: - # * assert_value(locator, pattern) - # * assert_not_value(locator, pattern) - # * verify_value_present(locator, pattern) - # * verify_not_value(locator, pattern) - # * wait_for_value(locator, pattern) - # * wait_for_not_value(locator, pattern) - def store_value locator, variable_name - command 'storeValue', locator, variable_name - end - - # Gets the text of an element. This works for any element that contains text. - # This command uses either the +textContent+ (Mozilla-like browsers) or the - # +innerText+ (IE-like browsers) of the element, which is the rendered text - # shown to the user. - # - # Related Assertions, automatically generated: - # * assert_text(locator, pattern) - # * assert_not_text(locator, pattern) - # * verify_text_present(locator, pattern) - # * verify_not_text(locator, pattern) - # * wait_for_text(locator, pattern) - # * wait_for_not_text(locator, pattern) - def store_text locator, variable_name - command 'storeText', locator, variable_name - end - - # Gets the result of evaluating the specified JavaScript snippet. The snippet - # may have multiple lines, but only the result of the last line will be - # returned. - # - # Note that, by default, the snippet will run in the context of the - # "selenium" object itself, so +this+ will refer to the Selenium object, and - # +window+ will refer to the top-level runner test window, not the window of - # your application. - # - # If you need a reference to the window of your application, you can refer to - # this.browserbot.getCurrentWindow() and if you need to use a locator to - # refer to a single element in your application page, you can use - # this.page().findElement("foo") where "foo" is your locator. - # - # Related Assertions, automatically generated: - # * assert_eval(script, pattern) - # * assert_not_eval(script, pattern) - # * verify_eval_present(script, pattern) - # * verify_not_eval(script, pattern) - # * wait_for_eval(script, pattern) - # * wait_for_not_eval(script, pattern) - def store_eval script, variable_name - command 'storeEval', script, variable_name - end - - # Gets whether a toggle-button (checkbox/radio) is checked. Fails if the - # specified element doesn't exist or isn't a toggle-button. - # - # Related Assertions, automatically generated: - # * assert_checked(locator) - # * assert_not_checked(locator) - # * verify_checked_present(locator) - # * verify_not_checked(locator) - # * wait_for_checked(locator) - # * wait_for_not_checked(locator) - def store_checked locator, variable_name - command 'storeChecked', locator, variable_name - end - - # Gets the text from a cell of a table. - # - # Related Assertions, automatically generated: - # * assert_table(locator, row, column, pattern) - # * assert_not_table(locator, row, column, pattern) - # * verify_table_present(locator, row, column, pattern) - # * verify_not_table(locator, row, column, pattern) - # * wait_for_table(locator, row, column, pattern) - # * wait_for_not_table(locator, row, column, pattern) - def store_table locator, row, column, variable_name - command 'storeTable', "#{locator}.#{row}.#{column}", variable_name - end - - # Verifies that the selected option of a drop-down satisfies the - # option_locator. - # - # option_locator is typically just an option label (e.g. "John Smith"). - # - # See the select command for more information about option locators. - # - # NOTE: store_selected is currently not supported by Selenium Core. - # - # Related Assertions, automatically generated: - # * assert_selected(locator, option_locator) - # * assert_not_selected(locator, option_locator) - # * verify_selected_present(locator, option_locator) - # * verify_not_selected(locator, option_locator) - # * wait_for_selected(locator, option_locator) - # * wait_for_not_selected(locator, option_locator) - def store_selected locator, option_locator, variable_name - raise 'Not supported in Selenium Core at the moment' - end - - # Gets option element ID for selected option in the specified select element. - # - # Related Assertions, automatically generated: - # * assert_selected_id(select_locator, pattern) - # * assert_not_selected_id(select_locator, pattern) - # * verify_selected_id(select_locator, pattern) - # * verify_not_selected_id(select_locator, pattern) - # * wait_for_selected_id(select_locator, pattern) - # * wait_for_not_selected_id(select_locator, pattern) - def store_selected_id select_locator, variable_name - command 'storeSelectedId', select_locator, variable_name - end - - # Gets all option element IDs for selected options in the specified select - # or multi-select element. - # - # Related Assertions, automatically generated: - # * assert_selected_ids(select_locator, pattern) - # * assert_not_selected_ids(select_locator, pattern) - # * verify_selected_ids(select_locator, pattern) - # * verify_not_selected_ids(select_locator, pattern) - # * wait_for_selected_ids(select_locator, pattern) - # * wait_for_not_selected_ids(select_locator, pattern) - def store_selected_ids select_locator, variable_name - command 'storeSelectedIds', select_locator, variable_name - end - - # Gets option index (option number, starting at 0) for selected option in the - # specified select element. - # - # Related Assertions, automatically generated: - # * assert_selected_index(select_locator, pattern) - # * assert_not_selected_index(select_locator, pattern) - # * verify_selected_index(select_locator, pattern) - # * verify_not_selected_index(select_locator, pattern) - # * wait_for_selected_index(select_locator, pattern) - # * wait_for_not_selected_index(select_locator, pattern) - def store_selected_index select_locator, variable_name - command 'storeSelectedIndex', select_locator, variable_name - end - - # Gets all option indexes (option number, starting at 0) for selected options - # in the specified select or multi-select element. - # - # Related Assertions, automatically generated: - # * assert_selected_indexes(select_locator, pattern) - # * assert_not_selected_indexes(select_locator, pattern) - # * verify_selected_indexes(select_locator, pattern) - # * verify_not_selected_indexes(select_locator, pattern) - # * wait_for_selected_indexes(select_locator, pattern) - # * wait_for_not_selected_indexes(select_locator, pattern) - def store_selected_indexes select_locator, variable_name - command 'storeSelectedIndexes', select_locator, variable_name - end - - # Gets option label (visible text) for selected option in the specified select - # element. - # - # Related Assertions, automatically generated: - # * assert_selected_label(select_locator, pattern) - # * assert_not_selected_label(select_locator, pattern) - # * verify_selected_label(select_locator, pattern) - # * verify_not_selected_label(select_locator, pattern) - # * wait_for_selected_label(select_locator, pattern) - # * wait_for_not_selected_label(select_locator, pattern) - def store_selected_label select_locator, variable_name - command 'storeSelectedLabel', select_locator, variable_name - end - - # Gets all option labels (visible text) for selected options in the specified - # select or multi-select element. - # - # Related Assertions, automatically generated: - # * assert_selected_labels(select_locator, pattern) - # * assert_not_selected_labels(select_locator, pattern) - # * verify_selected_labels(select_locator, pattern) - # * verify_not_selected_labels(select_locator, pattern) - # * wait_for_selected_labels(select_locator, pattern) - # * wait_for_not_selected_labels(select_locator, pattern) - def store_selected_labels select_locator, variable_name - command 'storeSelectedLabels', select_locator, variable_name - end - - # Gets option value (value attribute) for selected option in the specified - # select element. - # - # Related Assertions, automatically generated: - # * assert_selected_value(select_locator, pattern) - # * assert_not_selected_value(select_locator, pattern) - # * verify_selected_value(select_locator, pattern) - # * verify_not_selected_value(select_locator, pattern) - # * wait_for_selected_value(select_locator, pattern) - # * wait_for_not_selected_value(select_locator, pattern) - def store_selected_value select_locator, variable_name - command 'storeSelectedValue', select_locator, variable_name - end - - # Gets all option values (value attribute) for selected options in the specified - # select or multi-select element. - # - # Related Assertions, automatically generated: - # * assert_selected_values(select_locator, pattern) - # * assert_not_selected_values(select_locator, pattern) - # * verify_selected_values(select_locator, pattern) - # * verify_not_selected_values(select_locator, pattern) - # * wait_for_selected_values(select_locator, pattern) - # * wait_for_not_selected_values(select_locator, pattern) - def store_selected_values select_locator, variable_name - command 'storeSelectedValues', select_locator, variable_name - end - - # Determines whether some option in a drop-down menu is selected. - # - # Related Assertions, automatically generated: - # * assert_something_selected(select_locator) - # * assert_not_something_selected(select_locator) - # * verify_something_selected(select_locator) - # * verify_not_something_selected(select_locator) - # * wait_for_something_selected(select_locator) - # * wait_for_not_something_selected(select_locator) - def store_something_selected select_locator, variable_name - command 'storeSomethingSelected', select_locator, variable_name - end - - # Gets all option labels for selected options in the specified select or - # multi-select element. - # - # The +pattern+ for the automatically generated assertions can either take an - # array or a pattern. - # assert_selected_options 'fruits', ['apple', 'pear'] - # assert_selected_options 'fruits', 'a*,p*' - # - # Related Assertions, automatically generated: - # * assert_selected_options(locator, pattern) - # * assert_not_selected_options(locator, pattern) - # * verify_selected_options_present(locator, pattern) - # * verify_not_selected_options(locator, pattern) - # * wait_for_selected_options(locator, pattern) - # * wait_for_not_selected_options(locator, pattern) - def store_selected_options locator, variable_name - command 'storeSelectedOptions', locator, variable_name - end - - # Gets all option labels in the specified select drop-down. - # - # The +pattern+ for the automatically generated assertions can either take an - # array or a pattern. - # assert_select_options 'fruits', ['apple', 'pear'] - # assert_select_options 'fruits', 'a*,p*' - # - # Related Assertions, automatically generated: - # * assert_select_options(locator, pattern) - # * assert_not_select_options(locator, pattern) - # * verify_select_options_present(locator, pattern) - # * verify_not_select_options(locator, pattern) - # * wait_for_select_options(locator, pattern) - # * wait_for_not_select_options(locator, pattern) - def store_select_options locator, variable_name - command 'storeSelectOptions', locator, variable_name - end - - # Gets the value of an element attribute. - # - # Related Assertions, automatically generated: - # * assert_attribute(locator, attribute_name, pattern) - # * assert_not_attribute(locator, attribute_name, pattern) - # * verify_attribute_present(locator, attribute_name, pattern) - # * verify_not_attribute(locator, attribute_name, pattern) - # * wait_for_attribute(locator, attribute_name, pattern) - # * wait_for_not_attribute(locator, attribute_name, pattern) - def store_attribute locator, attribute_name, variable_name - command 'storeAttribute', "#{locator}@#{attribute_name}", variable_name - end - - # Check if these two elements have same parent and are ordered. Two - # same elements will not be considered ordered. - # - # NOTE: store_ordered is currently not supported by Selenium Core. - # - # Related Assertions, automatically generated: - # * assert_ordered(locator_1, locator_2) - # * assert_not_ordered(locator_1, locator_2) - # * verify_ordered(locator_1, locator_2) - # * verify_not_ordered(locator_1, locator_2) - # * wait_for_ordered(locator_1, locator_2) - # * wait_for_not_ordered(locator_1, locator_2) - def store_ordered locator_1, locator_2, variable_name - raise 'Not supported in Selenium Core at the moment' - end - - # Verifies that the specified text pattern appears somewhere on the rendered - # page shown to the user. - # - # Related Assertions, automatically generated: - # * assert_text_present(pattern) - # * assert_text_not_present(pattern) - # * verify_text_present(pattern) - # * verify_text_not_present(pattern) - # * wait_for_text_present(pattern) - # * wait_for_text_not_present(pattern) - def store_text_present pattern, variable_name - command 'storeTextPresent', pattern, variable_name - end - - # Verifies that the specified element is somewhere on the page. - # - # Related Assertions, automatically generated: - # * assert_element_present(locator) - # * assert_element_not_present(locator) - # * verify_element_present(locator) - # * verify_element_not_present(locator) - # * wait_for_element_present(locator) - # * wait_for_element_not_present(locator) - def store_element_present locator, variable_name - command 'storeElementPresent', locator, variable_name - end - - # Determines if the specified element is visible. An element can be rendered - # invisible by setting the CSS "visibility" property to "hidden", or the - # "display" property to "none", either for the element itself or one if its - # ancestors. This method will fail if the element is not present. - # - # Related Assertions, automatically generated: - # * assert_visible(locator) - # * assert_not_visible(locator) - # * verify_visible(locator) - # * verify_not_visible(locator) - # * wait_for_visible(locator) - # * wait_for_not_visible(locator) - def store_visible locator, variable_name - command 'storeVisible', locator, variable_name - end - - # Retrieves the height of an element. This method will fail if the element - # is not present. - # - # Related Assertions, automatically generated: - # * assert_element_height(locator, pattern) - # * assert_not_element_height(locator, pattern) - # * verify_element_height(locator, pattern) - # * verify_not_element_height(locator, pattern) - # * wait_for_element_height(locator, pattern) - # * wait_for_not_element_height(locator, pattern) - def store_element_height locator, variable_name - command 'storeElementHeight', locator, variable_name - end - - # Get the relative index of an element to its parent (starting from 0). - # The comment node and empty text node will be ignored. - # - # Related Assertions, automatically generated: - # * assert_element_index(locator, pattern) - # * assert_not_element_index(locator, pattern) - # * verify_element_index(locator, pattern) - # * verify_not_element_index(locator, pattern) - # * wait_for_element_index(locator, pattern) - # * wait_for_not_element_index(locator, pattern) - def store_element_index locator, variable_name - command 'storeElementIndex', locator, variable_name - end - - # Retrieves the width of an element. This method will fail if the element - # is not present. - # - # Related Assertions, automatically generated: - # * assert_element_width(locator, pattern) - # * assert_not_element_width(locator, pattern) - # * verify_element_width(locator, pattern) - # * verify_not_element_width(locator, pattern) - # * wait_for_element_width(locator, pattern) - # * wait_for_not_element_width(locator, pattern) - def store_element_width locator, variable_name - command 'storeElementWidth', locator, variable_name - end - - # Retrieves the horizontal position of an element. This method will fail - # if the element is not present. - # - # Related Assertions, automatically generated: - # * assert_element_position_left(locator, pattern) - # * assert_not_element_position_left(locator, pattern) - # * verify_element_position_left(locator, pattern) - # * verify_not_element_position_left(locator, pattern) - # * wait_for_element_position_left(locator, pattern) - # * wait_for_not_element_position_left(locator, pattern) - def store_element_position_left locator, variable_name - command 'storeElementPositionLeft', locator, variable_name - end - - # Retrieves the vertical position of an element. This method will fail - # if the element is not present. - # - # Related Assertions, automatically generated: - # * assert_element_position_top(locator, pattern) - # * assert_not_element_position_top(locator, pattern) - # * verify_element_position_top(locator, pattern) - # * verify_not_element_position_top(locator, pattern) - # * wait_for_element_position_top(locator, pattern) - # * wait_for_not_element_position_top(locator, pattern) - def store_element_position_top locator, variable_name - command 'storeElementPositionTop', locator, variable_name - end - - # Return the contents of the log. - # - # Related Assertions, automatically generated: - # * assert_log_messages(pattern) - # * assert_not_log_messages(pattern) - # * verify_log_messages(pattern) - # * verify_not_log_messages(pattern) - # * wait_for_log_messages(pattern) - # * wait_for_not_log_messages(pattern) - def store_log_messages variable_name - command 'storeLogMessages', variable_name - end - - # Determines whether the specified input element is editable, i.e. hasn't - # been disabled. This method will fail if the specified element isn't an - # input element. - # - # Related Assertions, automatically generated: - # * assert_editable(locator) - # * assert_not_editable(locator) - # * verify_editable(locator) - # * verify_not_editable(locator) - # * wait_for_editable(locator) - # * wait_for_not_editable(locator) - def store_editable locator, variable_name - command 'storeEditable', locator, variable_name - end - - # Returns the IDs of all buttons on the page. - # - # If a given button has no ID, it will appear as "" in this array. - # - # The +pattern+ for the automatically generated assertions can either take an - # array or a pattern. - # assert_all_buttons ['but1', 'but2'] - # assert_all_buttons 'but?,but?*' - # - # Related Assertions, automatically generated: - # * assert_all_buttons(pattern) - # * assert_not_all_buttons(pattern) - # * verify_all_buttons(pattern) - # * verify_not_all_buttons(pattern) - # * wait_for_all_buttons(pattern) - # * wait_for_not_all_buttons(pattern) - def store_all_buttons variable_name - command 'storeAllButtons', variable_name - end - - # Returns the IDs of all links on the page. - # - # If a given link has no ID, it will appear as "" in this array. - # - # The +pattern+ for the automatically generated assertions can either take an - # array or a pattern. - # assert_all_links ['link1', 'link2'] - # assert_all_links 'link?,link?*' - # - # Related Assertions, automatically generated: - # * assert_all_links(pattern) - # * assert_not_all_links(pattern) - # * verify_all_links(pattern) - # * verify_not_all_links(pattern) - # * wait_for_all_links(pattern) - # * wait_for_not_all_links(pattern) - def store_all_links variable_name - command 'storeAllLinks', variable_name - end - - # Returns the IDs of all input fields on the page. - # - # If a given field has no ID, it will appear as "" in this array. - # - # The +pattern+ for the automatically generated assertions can either take an - # array or a pattern. - # assert_all_fields ['field1', 'field2'] - # assert_all_fields 'field?,field?*' - # - # Related Assertions, automatically generated: - # * assert_all_fields(pattern) - # * assert_not_all_fields(pattern) - # * verify_all_fields(pattern) - # * verify_not_all_fields(pattern) - # * wait_for_all_fields(pattern) - # * wait_for_not_all_fields(pattern) - def store_all_fields variable_name - command 'storeAllFields', variable_name - end - - # Returns the entire HTML source between the opening and closing "html" tags. - # - # Related Assertions, automatically generated: - # * assert_html_source(pattern) - # * assert_not_html_source(pattern) - # * verify_html_source(pattern) - # * verify_not_html_source(pattern) - # * wait_for_html_source(pattern) - # * wait_for_not_html_source(pattern) - def store_html_source variable_name - command 'storeHtmlSource', variable_name - end - - # Returns the specified expression. - # - # This is useful because of JavaScript preprocessing. - # - # Related Assertions, automatically generated: - # * assert_expression(expression, pattern) - # * assert_not_expression(expression, pattern) - # * verify_expression(expression, pattern) - # * verify_not_expression(expression, pattern) - # * wait_for_expression(expression, pattern) - # * wait_for_not_expression(expression, pattern) - def store_expression expression, variable_name - command 'storeExpression', expression, variable_name - end - - # Determine whether current/locator identify the frame containing this - # running code. - # - # This is useful in proxy injection mode, where this code runs in every - # browser frame and window, and sometimes the selenium server needs to - # identify the "current" frame. In this case, when the test calls select_frame, - # this routine is called for each frame to figure out which one has been - # selected. The selected frame will return true, while all others will return - # false. - # - # NOTE: store_whether_this_frame_match_frame_expression is currently - # not supported by Selenium Core. - # - # Related Assertions, automatically generated: - # * assert_whether_this_frame_match_frame_expression(current_frame_string, target) - # * assert_not_whether_this_frame_match_frame_expression(current_frame_string, target) - # * verify_whether_this_frame_match_frame_expression(current_frame_string, target) - # * verify_not_whether_this_frame_match_frame_expression(current_frame_string, target) - # * wait_for_whether_this_frame_match_frame_expression(current_frame_string, target) - # * wait_for_not_whether_this_frame_match_frame_expression(current_frame_string, target) - def store_whether_this_frame_match_frame_expression current_frame_string, target, variable_name - raise 'Not supported in Selenium Core at the moment' - end - - # Determine whether current_window_string plus target identify the window - # containing this running code. - # - # This is useful in proxy injection mode, where this code runs in every browser - # frame and window, and sometimes the selenium server needs to identify the - # "current" window. In this case, when the test calls select_window, this routine - # is called for each window to figure out which one has been selected. The selected - # window will return true, while all others will return false. - # - # NOTE: store_whether_this_window_match_window_expression is currently - # not supported by Selenium Core. - # - # Related Assertions, automatically generated: - # * assert_whether_this_window_match_window_expression(current_window_string, target) - # * assert_not_whether_this_window_match_window_expression(current_window_string, target) - # * verify_whether_this_window_match_window_expression(current_window_string, target) - # * verify_not_whether_this_window_match_window_expression(current_window_string, target) - # * wait_for_whether_this_window_match_window_expression(current_window_string, target) - # * wait_for_not_whether_this_window_match_window_expression(current_window_string, target) - def store_whether_this_window_match_window_expression current_window_string, target, variable_name - raise 'Not supported in Selenium Core at the moment' - end - -private - # Generates all assertions for the accessors. - def self.generate_methods - public_instance_methods.each do |method| - case method - when 'store_alert_present', - 'store_prompt_present', - 'store_confirmation_present' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do - command command_name - end - end - when 'store_error_on_next', - 'store_failure_on_next', - 'store_alert', - 'store_all_window_ids', - 'store_all_window_names', - 'store_all_window_titles', - 'store_confirmation', - 'store_cookie', - 'store_log_messages', - 'store_mouse_speed', - 'store_prompt', - 'store_title', - 'store_body_text', - 'store_text_present', - 'store_element_present', - 'store_visible', - 'store_editable', - 'store_html_source', - 'store_checked', - 'store_something_selected' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |pattern| - command command_name, pattern - end - end - when 'store_attribute_from_all_windows', - 'store_value', - 'store_text', - 'store_eval', - 'store_cursor_position', - 'store_selected', - 'store_selected_id', - 'store_selected_ids', - 'store_selected_index', - 'store_selected_indexes', - 'store_selected_label', - 'store_selected_labels', - 'store_selected_value', - 'store_selected_values', - 'store_element_height', - 'store_element_index', - 'store_element_width', - 'store_element_position_left', - 'store_element_position_top', - 'store_expression', - 'store_ordered', - 'store_whether_this_frame_match_frame_expression', - 'store_whether_this_window_match_window_expression' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |arg1, arg2| - command command_name, arg1, arg2 - end - end - when 'store_all_buttons', - 'store_all_links', - 'store_all_fields' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |pattern| - command command_name, collection_arg(pattern) - end - end - when 'store_select_options', - 'store_selected_options' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |locator, pattern| - command command_name, locator, collection_arg(pattern) - end - end - when 'store_attribute' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |locator, attribute_name, pattern| - command command_name, "#{locator}@#{attribute_name}", pattern - end - end - when 'store_table' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |locator, row, column, pattern| - command command_name, "#{locator}.#{row}.#{column}", pattern - end - end - when 'store_absolute_location', - 'store_location' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |pattern| - if method == 'store_absolute_location' and pattern.is_a? Hash - pattern[:only_path] = false - end - - command command_name, url_arg(pattern) - end - end - when /^store_/ - raise 'internal error' - end - end - end - - # Generates all the assertions needed given a +store_method+. - def self.each_assertion store_method - before_negation = nil - after_negation = store_method.split('_')[1..-1] #throw away 'store' - if after_negation.last == 'present' - before_negation, after_negation = after_negation, after_negation.pop - end - - ['assert', 'verify', ['wait','for']].each do |action| - [nil, 'not'].each do |negation| - name = [action, before_negation, negation, after_negation].flatten.reject{|a|a.nil?} - method_name = name.join '_' - command = name.inject(name.shift.clone) {|n, p| n << p.capitalize} - yield method_name, command - end - end - end - - generate_methods -end diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_actions.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_actions.rb deleted file mode 100644 index 8eb86f10..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_actions.rb +++ /dev/null @@ -1,514 +0,0 @@ -# The actions available for SeleniumOnRails::TestBuilder tests. -# -# For each action +foo+ there's also an action +foo_and_wait+. -module SeleniumOnRails::TestBuilderActions - # Tell Selenium on Rails to clear the session and load any fixtures. DO - # NOT CALL THIS AGAINST NON-TEST DATABASES. - # The supported +options+ are :keep_session, - # :fixtures and :clear_tables - # setup - # setup :keep_session - # setup :fixtures => :all - # setup :keep_session, :fixtures => [:foo, :bar] - # setup :clear_tables => [:foo, :bar] - def setup options = {} - options = {options => nil} unless options.is_a? Hash - - opts = {:controller => 'selenium', :action => 'setup'} - opts[:keep_session] = true if options.has_key? :keep_session - - [:fixtures, :clear_tables].each do |key| - if (f = options[key]) - f = [f] unless f.is_a? Array - opts[key] = f.join ',' - end - end - - open opts - end - - # Includes a partial. - # The path is relative to the Selenium tests root. The starting _ and the file - # extension don't have to be specified. - # #include test/selenium/_partial.* - # include_partial 'partial' - # #include test/selenium/suite/_partial.* - # include_partial 'suite/partial' - # #include test/selenium/suite/_partial.* and provide local assigns - # include_partial 'suite/partial', :foo => bar - def include_partial path, local_assigns = {} - partial = @view.render :partial => path, :locals => local_assigns - @output << partial - end - - # Clicks on a link, button, checkbox or radio button. If the click action - # causes a new page to load (like a link usually does), call - # +wait_for_page_to_load+. - def click locator - command 'click', locator - end - - # Clicks on a link, button, checkbox or radio button. If the click action causes - # a new page to load (like a link usually does), call wait_for_page_to_load. - def click_at locator, coord_string - command 'clickAt', locator, coord_string - end - - # Explicitly simulate an event (e.g. "focus", "blur"), to - # trigger the corresponding "on_event_" handler. - def fire_event locator, event_name - command 'fireEvent', locator, event_name - end - - # Simulates a user pressing and releasing a key. - # - # +keycode+ is the numeric keycode of the key to be pressed, normally the - # ASCII value of that key. - def key_press locator, keycode - command 'keyPress', locator, keycode - end - - # Simulates a user pressing a key (without releasing it yet). - # - # +keycode+ is the numeric keycode of the key to be pressed, normally the - # ASCII value of that key. - def key_down locator, keycode - command 'keyDown', locator, keycode - end - - # Simulates a user releasing a key. - # - # +keycode+ is the numeric keycode of the key to be released, normally the - # ASCII value of that key. - def key_up locator, keycode - command 'keyUp', locator, keycode - end - - # Simulates a user hovering a mouse over the specified element. - def mouse_over locator - command 'mouseOver', locator - end - - # Simulates a user pressing the mouse button (without releasing it yet) on the - # specified element. - def mouse_down locator - command 'mouseDown', locator - end - - # Sets the value of an input field, as though you typed it in. - # - # Can also be used to set the value of combo boxes, check boxes, etc. In these - # cases, +value+ should be the value of the option selected, not the visible - # text. - def type locator, value - command 'type', locator, value - end - - # Check a toggle-button (checkbox/radio). - def check locator - command 'check', locator - end - - # Uncheck a toggle-button (checkbox/radio). - def uncheck locator - command 'uncheck', locator - end - - # Select an option from a drop-down using an option locator. - # - # Option locators provide different ways of specifying options of an HTML - # Select element (e.g. for selecting a specific option, or for asserting that - # the selected option satisfies a specification). There are several forms of - # Select Option Locator. - # - # * label=labelPattern - # matches options based on their labels, i.e. the visible text. (This is the - # default.) - # label=regexp:^[Oo]ther - # * value=valuePattern - # matches options based on their values. - # value=other - # * id=id - # matches options based on their ids. - # id=option1 - # * index=index - # matches an option based on its index (offset from zero). - # index=2 - # - # If no option locator prefix is provided, the default behaviour is to match - # on label. - def select locator, option_locator - command 'select', locator, option_locator - end - - # Add a selection to the set of selected options in a multi-select element - # using an option locator. - # - # See the #select command for more information about option locators. - def add_selection locator, option_locator - command 'addSelection', locator, option_locator - end - - # Remove a selection from the set of selected options in a multi-select - # element using an option locator. - # - # See the +select+ command for more information about option locators. - def remove_selection locator, option_locator - command 'removeSelection', locator, option_locator - end - - # Submit the specified form. This is particularly useful for forms without - # submit buttons, e.g. single-input "Search" forms. - def submit locator - command 'submit', locator - end - - # Opens an URL in the test frame. This accepts both relative and absolute - # URLs. The open command waits for the page to load before - # proceeding, i.e. you don't have to call +wait_for_page_to_load+. - # - # Note: The URL must be on the same domain as the runner HTML due to security - # restrictions in the browser (Same Origin Policy). - def open url - command 'open', url_arg(url) - end - - # Selects a popup window; once a popup window has been selected, all commands - # go to that window. To select the main window again, use +nil+ as the target. - def select_window window_id - command 'selectWindow', window_id||'null' - end - - # Waits for a popup window to appear and load up. - # - # The +timeout+ is specified in milliseconds. - def wait_for_popup window_id, timeout - command 'waitForPopUp', window_id||'null', timeout - end - - # By default, Selenium's overridden window.confirm() function will return - # +true+, as if the user had manually clicked OK. After running this command, - # the next call to confirm() will return +false+, as if the user had clicked - # Cancel. - def choose_cancel_on_next_confirmation - command 'chooseCancelOnNextConfirmation' - end - - # Instructs Selenium to return the specified answer string in response to the - # next JavaScript prompt (window.prompt()). - def answer_on_next_prompt answer - command 'answerOnNextPrompt', answer - end - - # Simulates the user clicking the "back" button on their browser. - def go_back - command 'goBack' - end - - # Simulates the user clicking the "Refresh" button on their browser. - def refresh - command 'refresh' - end - - # Simulates the user clicking the "close" button in the titlebar of a popup - # window or tab. - def close - command 'close' - end - - # Simulates the user pressing the alt key and hold it down until do_alt_up() - # is called or a new page is loaded. - def alt_key_down - command 'altKeyDown' - end - - # Simulates the user releasing the alt key. - def alt_key_up - command 'altKeyUp' - end - - # Halt the currently running test, and wait for the user to press the Continue - # button. This command is useful for debugging, but be careful when using it, - # because it will force automated tests to hang until a user intervenes manually. - # - # NOTE: break is a reserved word in Ruby, so we have to simulate - # Selenium core's break() with brake() - def brake - command 'break' - end - - # Simulates the user pressing the alt key and hold it down until do_control_up() - # is called or a new page is loaded. - def control_key_down - command 'controlKeyDown' - end - - # Simulates the user releasing the control key. - def control_key_up - command 'controlKeyUp' - end - - # Create a new cookie whose path and domain are same with those of current page - # under test, unless you specified a path for this cookie explicitly. - # - # Arguments: - # * name_value_pair - name and value of the cookie in a format "name=value" - # * options_string - options for the cookie. Currently supported options - # include 'path' and 'max_age'. The options_string's format is - # "path=/path/, max_age=60". The order of options are irrelevant, the - # unit of the value of 'max_age' is second. - def create_cookie name_value_pair, options_string - command 'createCookie', name_value_pair, options_string - end - - # Delete a named cookie with specified path. - def delete_cookie name, path - command 'deleteCookie', name, path - end - - # Double clicks on a link, button, checkbox or radio button. If the double click action - # causes a new page to load (like a link usually does), call wait_for_page_to_load. - def double_click locator - command 'doubleClick', locator - end - - # Doubleclicks on a link, button, checkbox or radio button. If the action causes a new page - # to load (like a link usually does), call wait_for_page_to_load. - def double_click_at locator, coord_string - command 'doubleClickAt', locator, coord_string - end - - # Drags an element a certain distance and then drops it. - def drag_and_drop locator, movements_string - command 'dragAndDrop', locator, movements_string - end - - # Drags an element and drops it on another element. - def drag_and_drop_to_object locator_of_object_to_be_dragged, locator_of_drag_destination_object - command 'dragAndDropToObject', locator_of_object_to_be_dragged, locator_of_drag_destination_object - end - - # Prints the specified message into the third table cell in your Selenese - # tables. - # Useful for debugging. - def echo message - command 'echo', message - end - - # Briefly changes the backgroundColor of the specified element yellow. - # Useful for debugging. - def highlight locator - command 'highlight', locator - end - - # Press the meta key and hold it down until doMetaUp() is called or - # a new page is loaded. - def meta_key_down - command 'metaKeyDown' - end - - # Release the meta key. - def meta_key_up - command 'metaKeyUp' - end - - # Simulates a user pressing the mouse button (without releasing it yet) on the specified - # element. - def mouse_down_at locator, coord_string - command 'mouseDownAt', locator, coord_string - end - - # Simulates a user moving the mouse. - def mouse_move locator - command 'mouseMove', locator - end - - # Simulates a user moving the mouse relative to the specified element. - def mouse_move_at locator, coord_string - command 'mouseMoveAt', locator, coord_string - end - - # Simulates the user moving the mouse off the specified element. - def mouse_out locator - command 'mouseOut', locator - end - - # Simulates the user releasing the mouse button on the specified element. - def mouse_up locator - command 'mouseUp', locator - end - - # Simulates a user pressing the mouse button (without releasing it yet) on the - # specified element. - def mouse_up_at locator, coord_string - command 'mouseUpAt', locator, coord_string - end - - # Opens a popup window (if a window with that ID isn't already open). After opening the - # window, you'll need to select it using the select_window command. - # - # 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). In those cases, you can force Selenium to notice the - # open window's name by using the Selenium openWindow command, using an empty (blank) url, - # like this: open_window("", "myFunnyWindow"). - def open_window url, window_id - command 'openWindow', url, window_id - end - - # Wait for the specified amount of time (in milliseconds). - def pause wait_time - command 'pause', wait_time - end - - # Unselects all of the selected options in a multi-select element. - def remove_all_selections locator - command 'removeAllSelections', locator - end - - # Selects a frame within the current window. (You may invoke this command multiple times - # to select nested frames.) To select the parent frame, use "relative=parent" as a - # locator; to select the top frame, use "relative=top". - # - # You may also use a DOM expression to identify the frame you want directly, like this: - # dom=frames["main"].frames["subframe"] - def select_frame locator - command 'selectFrame', locator - end - - # Moves the text cursor to the specified position in the given input element or textarea. - # This method will fail if the specified element isn't an input element or textarea. - def set_cursor_position locator, position - command 'setCursorPosition', locator, position - end - - # Configure the number of pixels between "mousemove" events during dragAndDrop commands - # (default=10). - # Setting this value to 0 means that we'll send a "mousemove" event to every single pixel - # in between the start location and the end location; that can be very slow, and may - # cause some browsers to force the JavaScript to timeout. - # - # If the mouse speed is greater than the distance between the two dragged objects, we'll - # just send one "mousemove" at the start location and then one final one at the end location. - def set_mouse_speed pixels - command 'setMouseSpeed', pixels - end - - # Press the shift key and hold it down until doShiftUp() is called or a new page - # is loaded. - def shift_key_down - command 'shiftKeyDown' - end - - # Release the shift key. - def shift_key_up - command 'shiftKeyUp' - end - - # This command is a synonym for store_expression. - def store expression, variable_name - command 'store', expression, variable_name - end - - # Simulates keystroke events on the specified element, as though you typed the value - # key-by-key. - # - # This is a convenience method for calling key_down, key_up, - # key_press for every character in the specified string; this is useful for - # dynamic UI widgets (like auto-completing combo boxes) that require explicit key events. - # - # Unlike the simple "type" command, which forces the specified value into the page directly, - # this command may or may not have any visible effect, even in cases where typing keys would - # normally have a visible effect. For example, if you use "type_keys" on a form - # element, you may or may not see the results of what you typed in the field. - # - # In some cases, you may need to use the simple "type" command to set the value of the field - # and then the "type_keys" command to send the keystroke events corresponding to - # what you just typed. - def type_keys locator, value - command 'typeKeys', locator, value - end - - # Gives focus to a window. - def window_focus window_name - command 'windowFocus', window_name - end - - # Resize window to take up the entire screen. - def window_maximize window_name - command 'windowMaximize', window_name - end - - # Writes a message to the status bar and adds a note to the browser-side log. - # - # +context+ is the message sent to the browser. - # - # +log_level_threshold+ can be +nil+, :debug, :info, - # :warn or :error. - def set_context context, log_level_threshold = nil - if log_level_threshold - command 'setContext', context, log_level_threshold.to_s - else - command 'setContext', context - end - end - - # Runs the specified JavaScript snippet repeatedly until it evaluates to - # +true+. The snippet may have multiple lines, but only the result of the last - # line will be considered. - # - # Note that, by default, the snippet will be run in the runner's test window, - # not in the window of your application. To get the window of your - # application, you can use the JavaScript snippet - # selenium.browserbot.getCurrentWindow(), and then run your - # JavaScript in there. - # - # +timeout+ is specified in milliseconds. - def wait_for_condition script, timeout - command 'waitForCondition', script, timeout - end - - # Specifies the amount of time that Selenium will wait for actions to - # complete. - # - # Actions that require waiting include +open+ and the wait_for* - # actions. - # - # The default timeout is 30 seconds. - # - # +timeout+ is specified in milliseconds. - def set_timeout timeout - command 'setTimeout', timeout - end - - # Waits for a new page to load. - # - # You can use this command instead of the +and_wait+ suffixes, - # +click_and_wait+, +select_and_wait+, +type_and_wait+ etc. (which are only - # available in the JS API). - # - # Selenium constantly keeps track of new pages loading, and sets a - # +newPageLoaded+ flag when it first notices a page load. Running any other - # Selenium command after turns the flag to +false+. Hence, if you want to wait - # for a page to load, you must wait immediately after a Selenium command that - # caused a page-load. - # - # +timeout+ is specified in milliseconds. - def wait_for_page_to_load timeout - command 'waitForPageToLoad', timeout - end - -private - # Generates the corresponding +_and_wait+ for each action. - def self.generate_and_wait_actions - public_instance_methods.each do |method| - define_method method + '_and_wait' do |*args| - methods_array = method.split("_") - send 'command_and_wait', methods_array.first.downcase + methods_array[1..-1].collect{|part| part.camelize}.join, *args - end - end - end - - generate_and_wait_actions -end - diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_accessors.rb.example b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_accessors.rb.example deleted file mode 100644 index 8f5d01fd..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_accessors.rb.example +++ /dev/null @@ -1,91 +0,0 @@ -# Mirrors the accessors specified in user-extensions.js from the selenium-core -module SeleniumOnRails::TestBuilderUserAccessors - - # Return the length of text of a specified element. - # - # Related Assertions, automatically generated: - # * assert_text_length(locator, variable) - # * assert_not_text_length(locator, length) - # * verify_text_length(locator, length) - # * verify_not_text_length(locator, length) - # * wait_for_text_length(locator, length) - # * wait_for_not_text_length(locator, length) - def store_text_length locator, variable_name - command 'storeTextLength', locator, variable_name - end - - # Checks if value entered more than once in textbox. - # - # Related Assertions, automatically generated: - # * assert_not_text_length(locator, text) - # * verify_text_length(locator, text) - # * verify_not_text_length(locator, text) - # * wait_for_text_length(locator, text) - # * wait_for_not_text_length(locator, text) - def assert_value_repeated locator, text - command 'assertValueRepeated', locator, text - end - - private - - def self.generate_methods - public_instance_methods.each do |method| - case method - when 'store_text_length' - each_assertion method do |assertion_method, command_name| - define_method assertion_method do |arg1, arg2| - command command_name, arg1, arg2 - end - end - when 'assert_value_repeated' - each_check method do |check_method, command_name| - define_method check_method do |arg1, arg2| - command command_name, arg1, arg2 - end - end - else - raise "Internal error: Don't know how to process user accessor: #{method}" - end - end - end - - # Generates all the assertions needed given a +store_method+. - def self.each_assertion store_method - before_negation = nil - after_negation = store_method.split('_')[1..-1] #throw away 'store' - if after_negation.last == 'present' - before_negation, after_negation = after_negation, after_negation.pop - end - - ['assert', 'verify', ['wait','for']].each do |action| - [nil, 'not'].each do |negation| - name = [action, before_negation, negation, after_negation].flatten.reject{|a|a.nil?} - method_name = name.join '_' - command = name.inject(name.shift.clone) {|n, p| n << p.capitalize} - yield method_name, command - end - end - end - - def self.each_check assert_method - before_negation = nil - after_negation = assert_method.split('_')[1..-1] #throw away 'assert' - if after_negation.last == 'present' - before_negation, after_negation = after_negation, after_negation.pop - end - - ['assert', 'verify', ['wait', 'for']].each do |action| - [nil, 'not'].each do |negation| - unless (action == 'assert' && negation.nil?) - name = [action, before_negation, negation, after_negation].flatten.reject{|a|a.nil?} - method_name = name.join '_' - command = name.inject(name.shift.clone) {|n, p| n << p.capitalize} - yield method_name, command - end - end - end - end - - generate_methods - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_actions.rb.example b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_actions.rb.example deleted file mode 100644 index 7a775fdd..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_actions.rb.example +++ /dev/null @@ -1,24 +0,0 @@ -# Mirrors the actions specified in user-extensions.js from the selenium-core -module SeleniumOnRails::TestBuilderUserActions - - # Types the text twice into a text box. - def type_repeated locator, text - command 'typeRepeated', locator, text - end - - private - - # Generates the corresponding +_and_wait+ for each action. - def self.generate_and_wait_actions - public_instance_methods.each do |method| - define_method method + '_and_wait' do |*args| - make_command_waiting do - send method, *args - end - end - end - end - - generate_and_wait_actions - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb b/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb deleted file mode 100644 index 1512fdc3..00000000 --- a/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'yaml' -require 'erb' - -class SeleniumOnRailsConfig - @@defaults = {:environments => ['test']} - def self.get var, default = nil - value = configs[var.to_s] - value ||= @@defaults[var] - value ||= default - value ||= yield if block_given? - value - end - - private - def self.configs - @@configs ||= nil - unless @@configs - files = [File.join(RAILS_ROOT, 'config', 'selenium.yml'), File.expand_path(File.dirname(__FILE__) + '/../config.yml')] - files.each do |file| - if File.exist?(file) - @@configs = YAML.load(ERB.new(IO.read(file)).result) - break - end - end - @@configs ||= {} - end - @@configs - end - -end diff --git a/vendor/plugins/selenium-on-rails/lib/views/layouts/layout.rhtml b/vendor/plugins/selenium-on-rails/lib/views/layouts/layout.rhtml deleted file mode 100644 index 16f827fd..00000000 --- a/vendor/plugins/selenium-on-rails/lib/views/layouts/layout.rhtml +++ /dev/null @@ -1,18 +0,0 @@ - - - - Selenium on Rails<%= defined?(@page_title) ? ": #{@page_title}" : '' %> - - - -<%= @content_for_layout %> - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/lib/views/record.rhtml b/vendor/plugins/selenium-on-rails/lib/views/record.rhtml deleted file mode 100644 index 65687553..00000000 --- a/vendor/plugins/selenium-on-rails/lib/views/record.rhtml +++ /dev/null @@ -1,5 +0,0 @@ - -<% @result.each_pair do |key, value| -%> - -<% end -%> -
<%= key %><%= value %>
diff --git a/vendor/plugins/selenium-on-rails/lib/views/selenium_helper.rb b/vendor/plugins/selenium-on-rails/lib/views/selenium_helper.rb deleted file mode 100644 index 4e178536..00000000 --- a/vendor/plugins/selenium-on-rails/lib/views/selenium_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -module SeleniumHelper - include SeleniumOnRails::SuiteRenderer - include SeleniumOnRails::FixtureLoader - - def test_case_name filename - File.basename(filename).sub(/\..*/,'').humanize - end - -end diff --git a/vendor/plugins/selenium-on-rails/lib/views/setup.rhtml b/vendor/plugins/selenium-on-rails/lib/views/setup.rhtml deleted file mode 100644 index 4091124b..00000000 --- a/vendor/plugins/selenium-on-rails/lib/views/setup.rhtml +++ /dev/null @@ -1,67 +0,0 @@ -<% @page_title = 'Setup' -%> -<% if defined?(@session_wiped) or @cleared_tables.any? or @loaded_fixtures.any? -%> -
- <% if defined?(@session_wiped) -%> -

The session is wiped clean.

- <% end-%> - <% if @cleared_tables.any? -%> -

The following database tables are cleared:

-
    - <% for table in @cleared_tables -%> -
  • <%= table %>
  • - <% end-%> -
- <% end -%> - <% if @loaded_fixtures.any? -%> -

The following fixtures are loaded:

-
    - <% for fixture in @loaded_fixtures -%> -
  • <%= fixture %>
  • - <% end-%> -
- <% end -%> -
-<% end -%> - -
-

This page can be used to setup your Selenium tests. The following options can be used:

-
-
keep_session
-
- Per default the session is reset, so add keep_session in order to keep the current session. - - -
open<%= url_for %>?keep_session 
-
-
fixtures
-
- Loads one or many fixtures into the database. This will destroy the current data you have in your database! Use all as name in order to load all fixtures, or specify which fixtures that should be loaded (delimited by commas).
- If a test needs different data than you have in your fixtures, you can add another fixture set. A fixture set is just a sub directory in /test/fixtures/ where you can add alternate fixtures (e.g. /test/fixtures/blank/users.yml). - - - - -
open<%= url_for :fixtures => 'all' %> 
open<%= url_for :fixtures => 'fixture' %> 
open<%= url_for :fixtures => 'fixture_one' %>,fixture_two 
- Available fixtures
- <% fixtures = available_fixtures -%> - <% for fixture_set in fixtures.keys.sort -%> - In the <%= fixture_set.blank? ? 'default' : "#{fixture_set}" %> fixture set: -
    - <% fixtures[fixture_set].unshift fixture_set.blank? ? 'all' : "#{fixture_set}/all" -%> - <% for fixture in fixtures[fixture_set] -%> -
  • <%= fixture %>
  • - <% end -%> -
- <% end -%> -
-
clear_tables
-
- Clears one or many database tables. Another way to do the same thing is to create an empty fixture in a new fixture set (see fixtures above). - - - -
open<%= url_for :clear_tables => 'sessions' %> 
open<%= url_for :clear_tables => 'sessions' %>,outgoing_messages 
-
-
- -
diff --git a/vendor/plugins/selenium-on-rails/lib/views/test_suite.rhtml b/vendor/plugins/selenium-on-rails/lib/views/test_suite.rhtml deleted file mode 100644 index 5973fc97..00000000 --- a/vendor/plugins/selenium-on-rails/lib/views/test_suite.rhtml +++ /dev/null @@ -1,26 +0,0 @@ -<% @page_title = test_suite_name @suite_path -%> - - - - - -<% for name, path in test_cases @suite_path -%> - -<% end -%> -
<%= @page_title %>
<%= link_to_test_case name, path %>
\ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/routes.rb b/vendor/plugins/selenium-on-rails/routes.rb deleted file mode 100644 index 9f3454d9..00000000 --- a/vendor/plugins/selenium-on-rails/routes.rb +++ /dev/null @@ -1,24 +0,0 @@ -module ActionController - module Routing #:nodoc: - class RouteSet #:nodoc: - alias_method :draw_without_selenium_routes, :draw - def draw - draw_without_selenium_routes do |map| - map.connect 'selenium/setup', - :controller => 'selenium', :action => 'setup' - map.connect 'selenium/tests/*testname', - :controller => 'selenium', :action => 'test_file' - map.connect 'selenium/postResults', - :controller => 'selenium', :action => 'record' - map.connect 'selenium/postResults/:logFile', - :controller => 'selenium', :action => 'record', :requirements => { :logFile => /.*/ } - map.connect 'selenium/*filename', - :controller => 'selenium', :action => 'support_file' - map.connect 'switch_environment', - :controller => 'switch_environment', :action => 'index' - yield map if block_given? - end - end - end - end -end diff --git a/vendor/plugins/selenium-on-rails/selenium-core/Blank.html b/vendor/plugins/selenium-on-rails/selenium-core/Blank.html deleted file mode 100644 index 838f933b..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/Blank.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/InjectedRemoteRunner.html b/vendor/plugins/selenium-on-rails/selenium-core/InjectedRemoteRunner.html deleted file mode 100644 index cb4432c0..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/InjectedRemoteRunner.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - -

selenium-rc initial page

- - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/RemoteRunner.html b/vendor/plugins/selenium-on-rails/selenium-core/RemoteRunner.html deleted file mode 100644 index da9f9771..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/RemoteRunner.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - -Selenium Remote Control - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
-

Selenium Functional Testing for Web Apps

- Open Source From ThoughtWorks and Friends -
-
- -
- - - -
- -
- -
-
- -
-
-

Command History:

-
- -
-
- -
- - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/SeleniumLog.html b/vendor/plugins/selenium-on-rails/selenium-core/SeleniumLog.html deleted file mode 100644 index 2b55fe76..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/SeleniumLog.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Selenium Log Console - - - - - - - - - - -
    - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/TestPrompt.html b/vendor/plugins/selenium-on-rails/selenium-core/TestPrompt.html deleted file mode 100644 index db202930..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/TestPrompt.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Select a Test Suite - - - - - - -
    - -

    - Test Suite: - -

    - -

    - -
    - Options - -

    - - -

    - -

    - -

    - -

    - - -
    - - -
    - - \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner-splash.html b/vendor/plugins/selenium-on-rails/selenium-core/TestRunner-splash.html deleted file mode 100644 index da2acdce..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner-splash.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
    Test SuiteCurrent TestControl Panel
     
    - - - -

    Selenium

    -

    by ThoughtWorks and friends

    - -

    -For more information on Selenium, visit - -

    -    http://selenium.openqa.org
    -
    - -
    - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.hta b/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.hta deleted file mode 100644 index ab481594..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.hta +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - Selenium Functional Test Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    -

    Selenium TestRunner -

    -
    -
    - Execute Tests - -
    - - - - -
    - -
    Fast
    -
    Slow
    -
    -
    -
     
    -
     
    -
    - -
    - - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Elapsed:00.00
    TestsCommands
    0run0passed
    0failed0failed
    0incomplete
    - -
    - Tools - - - - -
    - -
    -
    - -
    - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.html b/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.html deleted file mode 100644 index ab481594..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - Selenium Functional Test Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    -

    Selenium TestRunner -

    -
    -
    - Execute Tests - -
    - - - - -
    - -
    Fast
    -
    Slow
    -
    -
    -
     
    -
     
    -
    - -
    - - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Elapsed:00.00
    TestsCommands
    0run0passed
    0failed0failed
    0incomplete
    - -
    - Tools - - - - -
    - -
    -
    - -
    - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butmin.gif b/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butmin.gif deleted file mode 100644 index 7b7cefd5..00000000 Binary files a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butmin.gif and /dev/null differ diff --git a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butplus.gif b/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butplus.gif deleted file mode 100644 index 6d68cfa9..00000000 Binary files a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butplus.gif and /dev/null differ diff --git a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.css b/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.css deleted file mode 100644 index b64b2435..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.css +++ /dev/null @@ -1,298 +0,0 @@ -/****************************************************************************** -* Defines default styles for site pages. * -******************************************************************************/ -.hidden { - display: none; -} - -img{ - display: inline; - border: none; -} - -.box{ - background: #fcfcfc; - border: 1px solid #000; - border-color: blue; - color: #000000; - margin: 10px auto; - padding: 3px; - vertical-align: bottom; -} -a { - text-decoration: none; -} - -body { - background-color: #ffffff; - color: #000000; - font-family: Arial, Helvetica, sans-serif; - font-size: 10pt; -} - -h2 { - font-size: 140%; -} - -h3 { - font-size: 120%; -} - -h4 { - font-size: 100%; -} - -pre { - font-family: Courier New, Courier, monospace; - font-size: 80%; -} - -td, th { - font-family: Arial, Helvetica, sans-serif; - font-size: 10pt; - text-align: left; - vertical-align: top; -} - -th { - font-weight: bold; - vertical-align: bottom; -} - -ul { - list-style-type: square; -} - -#demoBox { - border-color: #000000; - border-style: solid; - border-width: 1px; - padding: 8px; - width: 24em; -} - -.footer { - margin-bottom: 0px; - text-align: center; -} - -/* Boxed table styles */ - -table.boxed { - border-spacing: 2px; - empty-cells: hide; -} - -td.boxed, th.boxed, th.boxedHeader { - background-color: #ffffff; - border-color: #000000; - border-style: solid; - border-width: 1px; - color: #000000; - padding: 2px; - padding-left: 8px; - padding-right: 8px; -} - -th.boxed { - background-color: #c0c0c0; -} - -th.boxedHeader { - background-color: #808080; - color: #ffffff; -} - -a.object { - color: #0000ff; -} - -li { - white-space: nowrap; -} - -ul { - list-style-type: square; - margin-left: 0px; - padding-left: 1em; -} - -.boxlevel1{ - background: #FFD700; -} - -.boxlevel2{ - background: #D2691E; -} - -.boxlevel3{ - background: #DCDCDC; -} - -.boxlevel4{ - background: #F5F5F5; -} - -.boxlevel5{ - background: #BEBEBE; -} - -.boxlevel6{ - background: #D3D3D3; -} - -.boxlevel7{ - background: #A9A9A9; -} - -.boxlevel8{ - background: #191970; -} - -.boxlevel9{ - background: #000080; -} - -.boxlevel10{ - background: #6495ED; -} - -.boxlevel11{ - background: #483D8B; -} - -.boxlevel12{ - background: #6A5ACD; -} - -.boxlevel13{ - background: #7B68EE; -} - -.boxlevel14{ - background: #8470FF; -} - -.boxlevel15{ - background: #0000CD; -} - -.boxlevel16{ - background: #4169E1; -} - -.boxlevel17{ - background: #0000FF; -} - -.boxlevel18{ - background: #1E90FF; -} - -.boxlevel19{ - background: #00BFFF; -} - -.boxlevel20{ - background: #87CEEB; -} - -.boxlevel21{ - background: #B0C4DE; -} - -.boxlevel22{ - background: #ADD8E6; -} - -.boxlevel23{ - background: #00CED1; -} - -.boxlevel24{ - background: #48D1CC; -} - -.boxlevel25{ - background: #40E0D0; -} - -.boxlevel26{ - background: #008B8B; -} - -.boxlevel27{ - background: #00FFFF; -} - -.boxlevel28{ - background: #E0FFFF; -} - -.boxlevel29{ - background: #5F9EA0; -} - -.boxlevel30{ - background: #66CDAA; -} - -.boxlevel31{ - background: #7FFFD4; -} - -.boxlevel32{ - background: #006400; -} - -.boxlevel33{ - background: #556B2F; -} - -.boxlevel34{ - background: #8FBC8F; -} - -.boxlevel35{ - background: #2E8B57; -} - -.boxlevel36{ - background: #3CB371; -} - -.boxlevel37{ - background: #20B2AA; -} - -.boxlevel38{ - background: #00FF7F; -} - -.boxlevel39{ - background: #7CFC00; -} - -.boxlevel40{ - background: #90EE90; -} - -.boxlevel41{ - background: #00FF00; -} - -.boxlevel41{ - background: #7FFF00; -} - -.boxlevel42{ - background: #00FA9A; -} - -.boxlevel43{ - background: #ADFF2F; -} - -.boxlevel44{ - background: #32CD32; -} \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.html b/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.html deleted file mode 100644 index 9158a50f..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - DOM Viewer - - - - - -

    DOM Viewer

    -

    This page is generated using JavaScript. If you see this text, your - browser doesn't support JavaScript.

    - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/selenium-domviewer.js b/vendor/plugins/selenium-on-rails/selenium-core/domviewer/selenium-domviewer.js deleted file mode 100644 index 941aab16..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/domviewer/selenium-domviewer.js +++ /dev/null @@ -1,205 +0,0 @@ -var HIDDEN="hidden"; -var LEVEL = "level"; -var PLUS_SRC="butplus.gif"; -var MIN_SRC="butmin.gif"; -var newRoot; -var maxColumns=1; - -function loadDomViewer() { - // See if the rootDocument variable has been set on this window. - var rootDocument = window.rootDocument; - - // If not look to the opener for an explicity rootDocument variable, otherwise, use the opener document - if (!rootDocument && window.opener) { - rootDocument = window.opener.rootDocument || window.opener.document; - } - - if (rootDocument) { - document.body.innerHTML = displayDOM(rootDocument); - } - else { - document.body.innerHTML = "Must specify rootDocument for window. This can be done by setting the rootDocument variable on this window, or on the opener window for a popup window."; - } -} - - -function displayDOM(root){ - var str = ""; - str+=""; - str += treeTraversal(root,0); - // to make table columns work well. - str += ""; - for (var i=0; i < maxColumns; i++) { - str+= ""; - } - str += ""; - str += "
        
    "; - return str; -} - -function checkForChildren(element){ - if(!element.hasChildNodes()) - return false; - - var nodes = element.childNodes; - var size = nodes.length; - var count=0; - - for(var i=0; i< size; i++){ - var node = nodes.item(i); - //if(node.toString()=="[object Text]"){ - //this is equalent to the above - //but will work with more browsers - if(node.nodeType!=1){ - count++; - } - } - - if(count == size) - return false; - else - return true; -} - -function treeTraversal(root, level){ - var str = ""; - var nodes= null; - var size = null; - //it is supposed to show the last node, - //but the last node is always nodeText type - //and we don't show it - if(!root.hasChildNodes()) - return "";//displayNode(root,level,false); - - nodes = root.childNodes; - size = nodes.length; - - for(var i=0; i< size; i++){ - var element = nodes.item(i); - //if the node is textNode, don't display - if(element.nodeType==1){ - str+= displayNode(element,level,checkForChildren(element)); - str+=treeTraversal(element, level+1); - } - } - return str; -} - -function displayNode(element, level, isLink){ - nodeContent = getNodeContent(element); - columns = Math.round((nodeContent.length / 12) + 0.5); - if (columns + level > maxColumns) { - maxColumns = columns + level; - } - var str =""; - for (var i=0; i < level; i++) - str+= " "; - str+=""; - if(isLink){ - str+=''; - str+=''; - } - str += nodeContent; - if(isLink) - str+=""; - return str; -} - -function getNodeContent(element) { - - str = ""; - id =""; - if (element.id != null && element.id != "") { - id = " ID(" + element.id +")"; - } - name =""; - if (element.name != null && element.name != "") { - name = " NAME(" + element.name + ")"; - } - value =""; - if (element.value != null && element.value != "") { - value = " VALUE(" + element.value + ")"; - } - href =""; - if (element.href != null && element.href != "") { - href = " HREF(" + element.href + ")"; - } - clazz = ""; - if (element.className != null && element.className != "") { - clazz = " CLASS(" + element.className + ")"; - } - src = ""; - if (element.src != null && element.src != "") { - src = " SRC(" + element.src + ")"; - } - alt = ""; - if (element.alt != null && element.alt != "") { - alt = " ALT(" + element.alt + ")"; - } - type = ""; - if (element.type != null && element.type != "") { - type = " TYPE(" + element.type + ")"; - } - text =""; - if (element.text != null && element.text != "" && element.text != "undefined") { - text = " #TEXT(" + trim(element.text) +")"; - } - str+=" "+ element.nodeName + id + alt + type + clazz + name + value + href + src + text + ""; - return str; - -} - -function trim(val) { - val2 = val.substring(0,40) + " "; - var spaceChr = String.fromCharCode(32); - var length = val2.length; - var retVal = ""; - var ix = length -1; - - while(ix > -1){ - if(val2.charAt(ix) == spaceChr) { - } else { - retVal = val2.substring(0, ix +1); - break; - } - ix = ix-1; - } - if (val.length > 40) { - retVal += "..."; - } - return retVal; -} - -function hide(hlink){ - var isHidden = false; - var image = hlink.firstChild; - if(image.src.toString().indexOf(MIN_SRC)!=-1){ - image.src=PLUS_SRC; - isHidden=true; - }else{ - image.src=MIN_SRC; - } - var rowObj= hlink.parentNode.parentNode; - var rowLevel = parseInt(rowObj.className.substring(LEVEL.length)); - - var sibling = rowObj.nextSibling; - var siblingLevel = sibling.className.substring(LEVEL.length); - if(siblingLevel.indexOf(HIDDEN)!=-1){ - siblingLevel = siblingLevel.substring(0,siblingLevel.length - HIDDEN.length-1); - } - siblingLevel=parseInt(siblingLevel); - while(sibling!=null && rowLevel - - - -Defines an object that runs Selenium commands. - -

    Element Locators

    -

    -Element Locators tell Selenium which HTML element a command refers to. -The format of a locator is:

    -
    -locatorType=argument -
    - -

    -We support the following strategies for locating elements: -

    - -
      -
    • identifier=id: -Select the element with the specified @id attribute. If no match is -found, select the first element whose @name attribute is id. -(This is normally the default; see below.)
    • -
    • id=id: -Select the element with the specified @id attribute.
    • - -
    • name=name: -Select the first element with the specified @name attribute. -
        -
      • username
      • -
      • name=username
      • -
      - -

      The name may optionally be followed by one or more element-filters, separated from the name by whitespace. If the filterType is not specified, value is assumed.

      - -
        -
      • name=flavour value=chocolate
      • -
      -
    • -
    • dom=javascriptExpression: - -Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object -Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block. -
        -
      • dom=document.forms['myForm'].myDropdown
      • -
      • dom=document.images[56]
      • -
      • dom=function foo() { return document.links[1]; }; foo();
      • -
      - -
    • - -
    • xpath=xpathExpression: -Locate an element using an XPath expression. -
        -
      • xpath=//img[@alt='The image alt text']
      • -
      • xpath=//table[@id='table1']//tr[4]/td[2]
      • -
      • xpath=//a[contains(@href,'#id1')]
      • -
      • xpath=//a[contains(@href,'#id1')]/@class
      • -
      • xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
      • -
      • xpath=//input[@name='name2' and @value='yes']
      • -
      • xpath=//*[text()="right"]
      • - -
      -
    • -
    • link=textPattern: -Select the link (anchor) element which contains text matching the -specified pattern. -
        -
      • link=The link text
      • -
      - -
    • - -
    • css=cssSelectorSyntax: -Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors 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. -
        -
      • css=a[href="#id3"]
      • -
      • css=span#firstChild + span
      • -
      -

      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).

      -
    • - -
    • ui=uiSpecifierString: -Locate an element by resolving the UI specifier string to another locator, and evaluating it. See the Selenium UI-Element Reference for more details. -
        -
      • ui=loginPages::loginButton()
      • -
      • ui=settingsPages::toggle(label=Hide Email)
      • -
      • ui=forumPages::postBody(index=2)//a[2]
      • -
      -
    • - -
    - -

    -Without an explicit locator prefix, Selenium uses the following default -strategies: -

    - -
      -
    • dom, for locators starting with "document."
    • -
    • xpath, for locators starting with "//"
    • -
    • identifier, otherwise
    • -
    - -

    Element Filters

    -
    -

    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.

    -

    Filters look much like locators, ie.

    -
    -filterType=argument
    - -

    Supported element-filters are:

    -

    value=valuePattern

    -
    -Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.
    -

    index=index

    -
    -Selects a single element based on its position in the list (offset from zero).
    -
    - -

    String-match Patterns

    - -

    -Various Pattern syntaxes are available for matching string values: -

    -
      -
    • glob:pattern: -Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a -kind of limited regular-expression syntax typically used in command-line -shells. In a glob pattern, "*" represents any sequence of characters, and "?" -represents any single character. Glob patterns match against the entire -string.
    • -
    • regexp:regexp: -Match a string using a regular-expression. The full power of JavaScript -regular-expressions is available.
    • -
    • regexpi:regexpi: -Match a string using a case-insensitive regular-expression.
    • -
    • exact:string: - -Match a string exactly, verbatim, without any of that fancy wildcard -stuff.
    • -
    -

    -If no pattern prefix is specified, Selenium assumes that it's a "glob" -pattern. -

    -

    -For commands that return multiple values (such as verifySelectOptions), -the string being matched is a comma-separated list of the return values, -where both commas and backslashes in the values are backslash-escaped. -When providing a pattern, the optional matching syntax (i.e. glob, -regexp, etc.) is specified once, as usual, at the beginning of the -pattern. -

    - - - -an element locator - -Clicks on a link, button, checkbox or radio button. If the click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -Double clicks on a link, button, checkbox or radio button. If the double click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Clicks on a link, button, checkbox or radio button. If the click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Doubleclicks on a link, button, checkbox or radio button. If the action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - - - - - -an element locator - -the event name, e.g. "focus" or "blur" - -Explicitly simulate an event, to trigger the corresponding "onevent" -handler. - - - - - -an element locator - -Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field. - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user pressing and releasing a key. - - - - - -Press the shift key and hold it down until doShiftUp() is called or a new page is loaded. - - - - - -Release the shift key. - - - - - -Press the meta key and hold it down until doMetaUp() is called or a new page is loaded. - - - - - -Release the meta key. - - - - - -Press the alt key and hold it down until doAltUp() is called or a new page is loaded. - - - - - -Release the alt key. - - - - - -Press the control key and hold it down until doControlUp() is called or a new page is loaded. - - - - - -Release the control key. - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user pressing a key (without releasing it yet). - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user releasing a key. - - - - - -an element locator - -Simulates a user hovering a mouse over the specified element. - - - - - -an element locator - -Simulates a user moving the mouse pointer away from the specified element. - - - - - -an element locator - -Simulates a user pressing the left mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -Simulates a user pressing the right mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the left mouse button (without releasing it yet) at -the specified location. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the right mouse button (without releasing it yet) at -the specified location. - - - - - -an element locator - -Simulates the event that occurs when the user releases the mouse button (i.e., stops -holding the button down) on the specified element. - - - - - -an element locator - -Simulates the event that occurs when the user releases the right mouse button (i.e., stops -holding the button down) on the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates the event that occurs when the user releases the mouse button (i.e., stops -holding the button down) at the specified location. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates the event that occurs when the user releases the right mouse button (i.e., stops -holding the button down) at the specified location. - - - - - -an element locator - -Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -the value to type - -Sets the value of an input field, as though you typed it in. - -

    Can also be used to set the value of combo boxes, check boxes, etc. In these cases, -value should be the value of the option selected, not the visible text.

    - -
    - - - -an element locator - -the value to type - -Simulates keystroke events on the specified element, as though you typed the value key-by-key. - -

    This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string; -this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.

    - -

    Unlike the simple "type" command, which forces the specified value into the page directly, this command -may or may not have any visible effect, even in cases where typing keys would normally have a visible effect. -For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in -the field.

    -

    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 -send the keystroke events corresponding to what you just typed.

    - -
    - - - -the number of milliseconds to pause after operation - -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., -the delay is 0 milliseconds. - - - - - -the execution speed in milliseconds. - -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., -the delay is 0 milliseconds. - -See also setSpeed. - - - - - -an element locator - -Check a toggle-button (checkbox/radio) - - - - - -an element locator - -Uncheck a toggle-button (checkbox/radio) - - - - - -an element locator identifying a drop-down menu - -an option locator (a label by default) - -Select an option from a drop-down using an option locator. - -

    -Option locators provide different ways of specifying options of an HTML -Select element (e.g. for selecting a specific option, or for asserting -that the selected option satisfies a specification). There are several -forms of Select Option Locator. -

    -
      -
    • label=labelPattern: -matches options based on their labels, i.e. the visible text. (This -is the default.) -
        -
      • label=regexp:^[Oo]ther
      • -
      -
    • -
    • value=valuePattern: -matches options based on their values. -
        -
      • value=other
      • -
      - - -
    • -
    • id=id: - -matches options based on their ids. -
        -
      • id=option1
      • -
      -
    • -
    • index=index: -matches an option based on its index (offset from zero). -
        - -
      • index=2
      • -
      -
    • -
    -

    -If no option locator prefix is provided, the default behaviour is to match on label. -

    - -
    - - - -an element locator identifying a multi-select box - -an option locator (a label by default) - -Add a selection to the set of selected options in a multi-select element using an option locator. - -@see #doSelect for details of option locators - - - - - -an element locator identifying a multi-select box - -an option locator (a label by default) - -Remove a selection from the set of selected options in a multi-select element using an option locator. - -@see #doSelect for details of option locators - - - - - -an element locator identifying a multi-select box - -Unselects all of the selected options in a multi-select element. - - - - - -an element locator for the form you want to submit - -Submit the specified form. This is particularly useful for forms without -submit buttons, e.g. single-input "Search" forms. - - - - - -the URL to open; may be relative or absolute - -Opens an URL in the test frame. This accepts both relative and absolute -URLs. - -The "open" command waits for the page to load before proceeding, -ie. the "AndWait" suffix is implicit. - -Note: The URL must be on the same domain as the runner HTML -due to security restrictions in the browser (Same Origin Policy). If you -need to open an URL on another domain, use the Selenium Server to start a -new browser session on that domain. - - - - - -the URL to open, which can be blank - -the JavaScript window ID of the window to select - -Opens a popup window (if a window with that ID isn't already open). -After opening the window, you'll need to select it using the selectWindow -command. - -

    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). -In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using -an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - -
    - - - -the JavaScript window ID of the window to select - -Selects a popup window using a window locator; once a popup window has been selected, all -commands go to that window. To select the main window again, use null -as the target. - -

    - -Window locators provide different ways of specifying the window object: -by title, by internal JavaScript "name," or by JavaScript variable. -

    -
      -
    • title=My Special Window: -Finds the window using the text that appears in the title bar. Be careful; -two windows can share the same title. If that happens, this locator will -just pick one. -
    • -
    • name=myWindow: -Finds the window using its internal JavaScript "name" property. This is the second -parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag) -(which Selenium intercepts). -
    • -
    • var=variableName: -Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current -application window, e.g. "window.foo = window.open(url);". In those cases, you can open the window using -"var=foo". -
    • -
    -

    -If no window locator prefix is provided, we'll try to guess what you mean like this:

    -

    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).

    -

    2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed -that this variable contains the return value from a call to the JavaScript window.open() method.

    -

    3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".

    -

    4.) If that fails, we'll try looping over all of the known windows to try to find the appropriate "title". -Since "title" is not necessarily unique, this may have unexpected behavior.

    - -

    If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages -which identify the names of windows created via window.open (and therefore intercepted by Selenium). You will see messages -like the following for each window as it is opened:

    - -

    debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"

    - -

    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). -(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 -an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - -
    - - - -an element locator identifying a frame or iframe - -Selects a frame within the current window. (You may invoke this command -multiple times to select nested frames.) To select the parent frame, use -"relative=parent" as a locator; to select the top frame, use "relative=top". -You can also select a frame by its 0-based index number; select the first frame with -"index=0", or the third frame with "index=2". - -

    You may also use a DOM expression to identify the frame you want directly, -like this: dom=frames["main"].frames["subframe"]

    - -
    - - - -true if the new frame is this code's window - -starting frame - -new frame (which might be relative to the current one) - -Determine whether current/locator identify the frame containing this running code. - -

    This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to identify -the "current" frame. In this case, when the test calls selectFrame, this -routine is called for each frame to figure out which one has been selected. -The selected frame will return true, while all others will return false.

    - -
    - - - -true if the new window is this code's window - -starting window - -new window (which might be relative to the current one, e.g., "_parent") - -Determine whether currentWindowString plus target identify the window containing this running code. - -

    This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to identify -the "current" window. In this case, when the test calls selectWindow, this -routine is called for each window to figure out which one has been selected. -The selected window will return true, while all others will return false.

    - -
    - - - -the JavaScript window "name" of the window that will appear (not the text of the title bar) - -a timeout in milliseconds, after which the action will return with an error - -Waits for a popup window to appear and load up. - - - - - -

    -By default, Selenium's overridden window.confirm() function will -return true, as if the user had manually clicked OK; after running -this command, the next call to confirm() will return false, as if -the user had clicked Cancel. Selenium will then resume using the -default behavior for future confirmations, automatically returning -true (OK) unless/until you explicitly call this command for each -confirmation. -

    -

    -Take note - every time a confirmation comes up, you must -consume it with a corresponding getConfirmation, or else -the next selenium operation will fail. -

    - -
    - - - -

    -Undo the effect of calling chooseCancelOnNextConfirmation. Note -that Selenium's overridden window.confirm() function will normally automatically -return true, as if the user had manually clicked OK, so you shouldn't -need to use this command unless for some reason you need to change -your mind prior to the next confirmation. After any confirmation, Selenium will resume using the -default behavior for future confirmations, automatically returning -true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each -confirmation. -

    -

    -Take note - every time a confirmation comes up, you must -consume it with a corresponding getConfirmation, or else -the next selenium operation will fail. -

    - -
    - - - -the answer to give in response to the prompt pop-up - -Instructs Selenium to return the specified answer string in response to -the next JavaScript prompt [window.prompt()]. - - - - - -Simulates the user clicking the "back" button on their browser. - - - - - -Simulates the user clicking the "Refresh" button on their browser. - - - - - -Simulates the user clicking the "close" button in the titlebar of a popup -window or tab. - - - - - -true if there is an alert - -Has an alert occurred? - -

    -This function never throws an exception -

    - -
    - - - -true if there is a pending prompt - -Has a prompt occurred? - -

    -This function never throws an exception -

    - -
    - - - -true if there is a pending confirmation - -Has confirm() been called? - -

    -This function never throws an exception -

    - -
    - - - -The message of the most recent JavaScript alert - -Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts. - -

    Getting an alert has the same effect as manually clicking OK. If an -alert is generated but you do not consume it with getAlert, the next Selenium action -will fail.

    - -

    Under Selenium, JavaScript alerts will NOT pop up a visible alert -dialog.

    - -

    Selenium does NOT support JavaScript alerts that are generated in a -page's onload() event handler. In this case a visible dialog WILL be -generated and Selenium will hang until someone manually clicks OK.

    - -
    - - - -the message of the most recent JavaScript confirmation dialog - -Retrieves the message of a JavaScript confirmation dialog generated during -the previous action. - -

    -By default, the confirm function will return true, having the same effect -as manually clicking OK. This can be changed by prior execution of the -chooseCancelOnNextConfirmation command. -

    -

    -If an confirmation is generated but you do not consume it with getConfirmation, -the next Selenium action will fail. -

    - -

    -NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible -dialog. -

    - -

    -NOTE: Selenium does NOT support JavaScript confirmations that are -generated in a page's onload() event handler. In this case a visible -dialog WILL be generated and Selenium will hang until you manually click -OK. -

    - -
    - - - -the message of the most recent JavaScript question prompt - -Retrieves the message of a JavaScript question prompt dialog generated during -the previous action. - -

    Successful handling of the prompt requires prior execution of the -answerOnNextPrompt command. If a prompt is generated but you -do not get/verify it, the next Selenium action will fail.

    - -

    NOTE: under Selenium, JavaScript prompts will NOT pop up a visible -dialog.

    - -

    NOTE: Selenium does NOT support JavaScript prompts that are generated in a -page's onload() event handler. In this case a visible dialog WILL be -generated and Selenium will hang until someone manually clicks OK.

    - -
    - - - -the absolute URL of the current page - -Gets the absolute URL of the current page. - - - - - -the title of the current page - -Gets the title of the current page. - - - - - -the entire text of the page - -Gets the entire text of the page. - - - - - -the element value, or "on/off" for checkbox/radio elements - -an element locator - -Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter). -For checkbox/radio elements, the value will be "on" or "off" depending on -whether the element is checked or not. - - - - - -the text of the element - -an element locator - -Gets the text of an element. This works for any element that contains -text. This command uses either the textContent (Mozilla-like browsers) or -the innerText (IE-like browsers) of the element, which is the rendered -text shown to the user. - - - - - -an element locator - -Briefly changes the backgroundColor of the specified element yellow. Useful for debugging. - - - - - -the results of evaluating the snippet - -the JavaScript snippet to run - -Gets the result of evaluating the specified JavaScript snippet. The snippet may -have multiple lines, but only the result of the last line will be returned. - -

    Note that, by default, the snippet will run in the context of the "selenium" -object itself, so this will refer to the Selenium object. Use window to -refer to the window of your application, e.g. window.document.getElementById('foo')

    - -

    If you need to use -a locator to refer to a single element in your application page, you can -use this.browserbot.findElement("id=foo") where "id=foo" is your locator.

    - -
    - - - -true if the checkbox is checked, false otherwise - -an element locator pointing to a checkbox or radio button - -Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button. - - - - - -the text from the specified cell - -a cell address, e.g. "foo.1.4" - -Gets the text from a cell of a table. The cellAddress syntax -tableLocator.row.column, where row and column start at 0. - - - - - -an array of all selected option labels in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option labels (visible text) for selected options in the specified select or multi-select element. - - - - - -the selected option label in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option label (visible text) for selected option in the specified select element. - - - - - -an array of all selected option values in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option values (value attributes) for selected options in the specified select or multi-select element. - - - - - -the selected option value in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option value (value attribute) for selected option in the specified select element. - - - - - -an array of all selected option indexes in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element. - - - - - -the selected option index in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option index (option number, starting at 0) for selected option in the specified select element. - - - - - -an array of all selected option IDs in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option element IDs for selected options in the specified select or multi-select element. - - - - - -the selected option ID in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option element ID for selected option in the specified select element. - - - - - -true if some option has been selected, false otherwise - -an element locator identifying a drop-down menu - -Determines whether some option in a drop-down menu is selected. - - - - - -an array of all option labels in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option labels in the specified select drop-down. - - - - - -the value of the specified attribute - -an element locator followed by an @ sign and then the name of the attribute, e.g. "foo@bar" - -Gets the value of an element attribute. The value of the attribute may -differ across browsers (this is the case for the "style" attribute, for -example). - - - - - -true if the pattern matches the text, false otherwise - -a pattern to match with the text of the page - -Verifies that the specified text pattern appears somewhere on the rendered page shown to the user. - - - - - -true if the element is present, false otherwise - -an element locator - -Verifies that the specified element is somewhere on the page. - - - - - -true if the specified element is visible, false otherwise - -an element locator - -Determines if the specified element is visible. An -element can be rendered invisible by setting the CSS "visibility" -property to "hidden", or the "display" property to "none", either for the -element itself or one if its ancestors. This method will fail if -the element is not present. - - - - - -true if the input element is editable, false otherwise - -an element locator - -Determines whether the specified input element is editable, ie hasn't been disabled. -This method will fail if the specified element isn't an input element. - - - - - -the IDs of all buttons on the page - -Returns the IDs of all buttons on the page. - -

    If a given button has no ID, it will appear as "" in this array.

    - -
    - - - -the IDs of all links on the page - -Returns the IDs of all links on the page. - -

    If a given link has no ID, it will appear as "" in this array.

    - -
    - - - -the IDs of all field on the page - -Returns the IDs of all input fields on the page. - -

    If a given field has no ID, it will appear as "" in this array.

    - -
    - - - -the set of values of this attribute from all known windows. - -name of an attribute on the windows - -Returns every instance of some attribute from all known windows. - - - - - -an element locator - -offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - -deprecated - use dragAndDrop instead - - - - - -the number of pixels between "mousemove" events - -Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10). -

    Setting this value to 0 means that we'll send a "mousemove" event to every single pixel -in between the start location and the end location; that can be very slow, and may -cause some browsers to force the JavaScript to timeout.

    - -

    If the mouse speed is greater than the distance between the two dragged objects, we'll -just send one "mousemove" at the start location and then one final one at the end location.

    - -
    - - - -the number of pixels between "mousemove" events during dragAndDrop commands (default=10) - -Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10). - - - - - -an element locator - -offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - -Drags an element a certain distance and then drops it - - - - - -an element to be dragged - -an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged is dropped - -Drags an element and drops it on another element - - - - - -Gives focus to the currently selected window - - - - - -Resize currently selected window to take up the entire screen - - - - - -the IDs of all windows that the browser knows about. - -Returns the IDs of all windows that the browser knows about. - - - - - -the names of all windows that the browser knows about. - -Returns the names of all windows that the browser knows about. - - - - - -the titles of all windows that the browser knows about. - -Returns the titles of all windows that the browser knows about. - - - - - -the entire HTML source - -Returns the entire HTML source between the opening and -closing "html" tags. - - - - - -an element locator pointing to an input element or textarea - -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. - -Moves the text cursor to the specified position in the given input element or textarea. -This method will fail if the specified element isn't an input element or textarea. - - - - - -of relative index of the element to its parent (starting from 0) - -an element locator pointing to an element - -Get the relative index of an element to its parent (starting from 0). The comment node and empty text node -will be ignored. - - - - - -true if element1 is the previous sibling of element2, false otherwise - -an element locator pointing to the first element - -an element locator pointing to the second element - -Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will -not be considered ordered. - - - - - -of pixels from the edge of the frame. - -an element locator pointing to an element OR an element itself - -Retrieves the horizontal position of an element - - - - - -of pixels from the edge of the frame. - -an element locator pointing to an element OR an element itself - -Retrieves the vertical position of an element - - - - - -width of an element in pixels - -an element locator pointing to an element - -Retrieves the width of an element - - - - - -height of an element in pixels - -an element locator pointing to an element - -Retrieves the height of an element - - - - - -the numerical position of the cursor in the field - -an element locator pointing to an input element or textarea - -Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers. - -

    Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to -return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as SEL-243.

    -This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.
    - -
    - - - -the value passed in - -the value to return - -Returns the specified expression. - -

    This is useful because of JavaScript preprocessing. -It is used to generate commands like assertExpression and waitForExpression.

    - -
    - - - -the number of nodes that match the specified xpath - -the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you. - -Returns the number of nodes that match the specified xpath, eg. "//table" would give -the number of tables. - - - - - -an element locator pointing to an element - -a string to be used as the ID of the specified element - -Temporarily sets the "id" attribute of the specified element, so you can locate it in the future -using its ID rather than a slow/complicated XPath. This ID will disappear once the page is -reloaded. - - - - - -boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath - -Specifies whether Selenium should use the native in-browser implementation -of XPath (if any native version is available); if you pass "false" to -this function, we will always use our pure-JavaScript xpath library. -Using the pure-JS xpath library can improve the consistency of xpath -element locators between different browser vendors, but the pure-JS -version is much slower than the native implementations. - - - - - -boolean, true means we'll ignore attributes without value at the expense of xpath "correctness"; false means we'll sacrifice speed for correctness. - -Specifies whether Selenium will ignore xpath attributes that have no -value, i.e. are the empty string, when using the non-native xpath -evaluation engine. You'd want to do this for performance reasons in IE. -However, this could break certain xpaths, for example an xpath that looks -for an attribute whose value is NOT the empty string. - -The hope is that such xpaths are relatively rare, but the user should -have the option of using them. Note that this only influences xpath -evaluation when using the ajaxslt engine (i.e. not "javascript-xpath"). - - - - - -the JavaScript snippet to run - -a timeout in milliseconds, after which this command will return with an error - -Runs the specified JavaScript snippet repeatedly until it evaluates to "true". -The snippet may have multiple lines, but only the result of the last line -will be considered. - -

    Note that, by default, the snippet will be run in the runner's test window, not in the window -of your application. To get the window of your application, you can use -the JavaScript snippet selenium.browserbot.getCurrentWindow(), and then -run your JavaScript in there

    - -
    - - - -a timeout in milliseconds, after which the action will return with an error - -Specifies the amount of time that Selenium will wait for actions to complete. - -

    Actions that require waiting include "open" and the "waitFor*" actions.

    -The default timeout is 30 seconds.
    - -
    - - - -a timeout in milliseconds, after which this command will return with an error - -Waits for a new page to load. - -

    You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc. -(which are only available in the JS API).

    - -

    Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded" -flag when it first notices a page load. Running any other Selenium command after -turns the flag to false. Hence, if you want to wait for a page to load, you must -wait immediately after a Selenium command that caused a page-load.

    - -
    - - - -FrameAddress from the server side - -a timeout in milliseconds, after which this command will return with an error - -Waits for a new frame to load. - -

    Selenium constantly keeps track of new pages and frames loading, -and sets a "newPageLoaded" flag when it first notices a page load.

    - -See waitForPageToLoad for more information.
    - -
    - - - -all cookies of the current page under test - -Return all cookies of the current page under test. - - - - - -the value of the cookie - -the name of the cookie - -Returns the value of the cookie with the specified name, or throws an error if the cookie is not present. - - - - - -true if a cookie with the specified name is present, or false otherwise. - -the name of the cookie - -Returns true if a cookie with the specified name is present, or false otherwise. - - - - - -name and value of the cookie in a format "name=value" - -options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'. the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will usually fail. - -Create a new cookie whose path and domain are same with those of current page -under test, unless you specified a path for this cookie explicitly. - - - - - -the name of the cookie to be deleted - -options for the cookie. Currently supported options include 'path', 'domain' and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". The order of options are irrelevant. Note that specifying a domain that isn't a subset of the current domain will usually fail. - -Delete a named cookie with specified path and domain. Be careful; to delete a cookie, you -need to delete it using the exact same path and domain that were used to create the cookie. -If the path is wrong, or the domain is wrong, the cookie simply won't be deleted. Also -note that specifying a domain that isn't a subset of the current domain will usually fail. - -Since there's no way to discover at runtime the original path and domain of a given cookie, -we've added an option called 'recurse' to try all sub-domains of the current domain with -all paths that are a subset of the current path. Beware; this option can be slow. In -big-O notation, it operates in O(n*m) time, where n is the number of dots in the domain -name and m is the number of slashes in the path. - - - - - -Calls deleteCookie with recurse=true on all cookies visible to the current page. -As noted on the documentation for deleteCookie, recurse=true can be much slower -than simply deleting the cookies using a known domain/path. - - - - - -one of the following: "debug", "info", "warn", "error" or "off" - -Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded. -Valid logLevel strings are: "debug", "info", "warn", "error" or "off". -To see the browser logs, you need to -either show the log window in GUI mode, or enable browser-side logging in Selenium RC. - - - - - -the JavaScript snippet to run - -Creates a new "script" tag in the body of the current test window, and -adds the specified text into the body of the command. Scripts run in -this way can often be debugged more easily than scripts executed using -Selenium's "getEval" command. Beware that JS exceptions thrown in these script -tags aren't managed by Selenium, so you should probably wrap your script -in try/catch blocks if there is any chance that the script will throw -an exception. - - - - - -the name of the strategy to define; this should use only letters [a-zA-Z] with no spaces or other punctuation. - -a string defining the body of a function in JavaScript. For example: return inDocument.getElementById(locator); - -Defines a new function for Selenium to locate elements on the page. -For example, -if you define the strategy "foo", and someone runs click("foo=blah"), we'll -run your function, passing you the string "blah", and click on the element -that your function -returns, or throw an "Element not found" error if your function returns null. - -We'll pass three arguments to your function: -
      -
    • locator: the string the user passed in
    • -
    • inWindow: the currently selected window
    • -
    • inDocument: the currently selected document
    • -
    -The function must return null if the element can't be found.
    - -
    - - - -the path to the file to persist the screenshot as. No filename extension will be appended by default. Directories will not be created if they do not exist, and an exception will be thrown, possibly by native code. - -a kwargs string that modifies the way the screenshot is captured. Example: "background=#CCFFDD" . Currently valid options:
    background
    the background CSS for the HTML document. This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed (possibly obscuring black text).
    - -Saves the entire contents of the current window canvas to a PNG file. -Contrast this with the captureScreenshot command, which captures the -contents of the OS viewport (i.e. whatever is currently being displayed -on the monitor), and is implemented in the RC only. Currently this only -works in Firefox when running in chrome mode, and in IE non-HTA using -the EXPERIMENTAL "Snapsie" utility. The Firefox implementation is mostly -borrowed from the Screengrab! Firefox extension. Please see -http://www.screengrab.org and http://snapsie.sourceforge.net/ for -details. - -
    - - - -the name of the rollup command - -keyword arguments string that influences how the rollup expands into commands - -Executes a command rollup, which is a series of commands with a unique -name, and optionally arguments that control the generation of the set of -commands. If any one of the rolled-up commands fails, the rollup is -considered to have failed. Rollups may also contain nested rollups. - - - - - -the Javascript content of the script to add - -(optional) the id of the new script tag. If specified, and an element with this id already exists, this operation will fail. - -Loads script content into a new script tag in the Selenium document. This -differs from the runScript command in that runScript adds the script tag -to the document of the AUT, not the Selenium document. The following -entities in the script content are replaced by the characters they -represent: - - < - > - & - -The corresponding remove command is removeScript. - - - - - -the id of the script element to remove. - -Removes a script tag from the Selenium document identified by the given -id. Does nothing if the referenced tag doesn't exist. - - - - - -name of the desired library Only the following three can be chosen: ajaxslt - Google's library javascript - Cybozu Labs' faster library default - The default library. Currently the default library is ajaxslt. If libraryName isn't one of these three, then no change will be made. - -Allows choice of one of the available libraries. - - - - - -the amount of time to sleep (in milliseconds) - -Wait for the specified amount of time (in milliseconds) - - - - - -Halt the currently running test, and wait for the user to press the Continue button. -This command is useful for debugging, but be careful when using it, because it will -force automated tests to hang until a user intervenes manually. - - - - - -the value to store - -the name of a variable in which the result is to be stored. - -This command is a synonym for storeExpression. - - - - - -the message to print - -Prints the specified message into the third table cell in your Selenese tables. -Useful for debugging. - - - - - -an element locator identifying a drop-down menu - -an option locator, typically just an option label (e.g. "John Smith") - -Verifies that the selected option of a drop-down satisfies the optionSpecifier. Note that this command is deprecated; you should use assertSelectedLabel, assertSelectedValue, assertSelectedIndex, or assertSelectedId instead. - -

    See the select command for more information about option locators.

    - -
    - - - -The failure message we should expect. This command will fail if the wrong failure message appears. - -Tell Selenium to expect a failure on the next command execution. - - - - - -The error message we should expect. This command will fail if the wrong error message appears. - -Tell Selenium to expect an error on the next command execution. - - - -
    diff --git a/vendor/plugins/selenium-on-rails/selenium-core/iedoc.xml b/vendor/plugins/selenium-on-rails/selenium-core/iedoc.xml deleted file mode 100644 index 0b9f7a74..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/iedoc.xml +++ /dev/null @@ -1,1800 +0,0 @@ - - - - -Defines an object that runs Selenium commands. - -

    Element Locators

    -

    -Element Locators tell Selenium which HTML element a command refers to. -The format of a locator is:

    -
    -locatorType=argument -
    - -

    -We support the following strategies for locating elements: -

    - -
      -
    • identifier=id: -Select the element with the specified @id attribute. If no match is -found, select the first element whose @name attribute is id. -(This is normally the default; see below.)
    • -
    • id=id: -Select the element with the specified @id attribute.
    • - -
    • name=name: -Select the first element with the specified @name attribute. -
        -
      • username
      • -
      • name=username
      • -
      - -

      The name may optionally be followed by one or more element-filters, separated from the name by whitespace. If the filterType is not specified, value is assumed.

      - -
        -
      • name=flavour value=chocolate
      • -
      -
    • -
    • dom=javascriptExpression: - -Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object -Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block. -
        -
      • dom=document.forms['myForm'].myDropdown
      • -
      • dom=document.images[56]
      • -
      • dom=function foo() { return document.links[1]; }; foo();
      • -
      - -
    • - -
    • xpath=xpathExpression: -Locate an element using an XPath expression. -
        -
      • xpath=//img[@alt='The image alt text']
      • -
      • xpath=//table[@id='table1']//tr[4]/td[2]
      • -
      • xpath=//a[contains(@href,'#id1')]
      • -
      • xpath=//a[contains(@href,'#id1')]/@class
      • -
      • xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
      • -
      • xpath=//input[@name='name2' and @value='yes']
      • -
      • xpath=//*[text()="right"]
      • - -
      -
    • -
    • link=textPattern: -Select the link (anchor) element which contains text matching the -specified pattern. -
        -
      • link=The link text
      • -
      - -
    • - -
    • css=cssSelectorSyntax: -Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors 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. -
        -
      • css=a[href="#id3"]
      • -
      • css=span#firstChild + span
      • -
      -

      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).

      -
    • - -
    • ui=uiSpecifierString: -Locate an element by resolving the UI specifier string to another locator, and evaluating it. See the Selenium UI-Element Reference for more details. -
        -
      • ui=loginPages::loginButton()
      • -
      • ui=settingsPages::toggle(label=Hide Email)
      • -
      • ui=forumPages::postBody(index=2)//a[2]
      • -
      -
    • - -
    - -

    -Without an explicit locator prefix, Selenium uses the following default -strategies: -

    - -
      -
    • dom, for locators starting with "document."
    • -
    • xpath, for locators starting with "//"
    • -
    • identifier, otherwise
    • -
    - -

    Element Filters

    -
    -

    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.

    -

    Filters look much like locators, ie.

    -
    -filterType=argument
    - -

    Supported element-filters are:

    -

    value=valuePattern

    -
    -Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.
    -

    index=index

    -
    -Selects a single element based on its position in the list (offset from zero).
    -
    - -

    String-match Patterns

    - -

    -Various Pattern syntaxes are available for matching string values: -

    -
      -
    • glob:pattern: -Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a -kind of limited regular-expression syntax typically used in command-line -shells. In a glob pattern, "*" represents any sequence of characters, and "?" -represents any single character. Glob patterns match against the entire -string.
    • -
    • regexp:regexp: -Match a string using a regular-expression. The full power of JavaScript -regular-expressions is available.
    • -
    • regexpi:regexpi: -Match a string using a case-insensitive regular-expression.
    • -
    • exact:string: - -Match a string exactly, verbatim, without any of that fancy wildcard -stuff.
    • -
    -

    -If no pattern prefix is specified, Selenium assumes that it's a "glob" -pattern. -

    -

    -For commands that return multiple values (such as verifySelectOptions), -the string being matched is a comma-separated list of the return values, -where both commas and backslashes in the values are backslash-escaped. -When providing a pattern, the optional matching syntax (i.e. glob, -regexp, etc.) is specified once, as usual, at the beginning of the -pattern. -

    - - - -an element locator - -Clicks on a link, button, checkbox or radio button. If the click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -Double clicks on a link, button, checkbox or radio button. If the double click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Clicks on a link, button, checkbox or radio button. If the click action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Doubleclicks on a link, button, checkbox or radio button. If the action -causes a new page to load (like a link usually does), call -waitForPageToLoad. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - - - - - -an element locator - -the event name, e.g. "focus" or "blur" - -Explicitly simulate an event, to trigger the corresponding "onevent" -handler. - - - - - -an element locator - -Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field. - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user pressing and releasing a key. - - - - - -Press the shift key and hold it down until doShiftUp() is called or a new page is loaded. - - - - - -Release the shift key. - - - - - -Press the meta key and hold it down until doMetaUp() is called or a new page is loaded. - - - - - -Release the meta key. - - - - - -Press the alt key and hold it down until doAltUp() is called or a new page is loaded. - - - - - -Release the alt key. - - - - - -Press the control key and hold it down until doControlUp() is called or a new page is loaded. - - - - - -Release the control key. - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user pressing a key (without releasing it yet). - - - - - -an element locator - -Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". - -Simulates a user releasing a key. - - - - - -an element locator - -Simulates a user hovering a mouse over the specified element. - - - - - -an element locator - -Simulates a user moving the mouse pointer away from the specified element. - - - - - -an element locator - -Simulates a user pressing the left mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -Simulates a user pressing the right mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the left mouse button (without releasing it yet) at -the specified location. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the right mouse button (without releasing it yet) at -the specified location. - - - - - -an element locator - -Simulates the event that occurs when the user releases the mouse button (i.e., stops -holding the button down) on the specified element. - - - - - -an element locator - -Simulates the event that occurs when the user releases the right mouse button (i.e., stops -holding the button down) on the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates the event that occurs when the user releases the mouse button (i.e., stops -holding the button down) at the specified location. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates the event that occurs when the user releases the right mouse button (i.e., stops -holding the button down) at the specified location. - - - - - -an element locator - -Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. - -Simulates a user pressing the mouse button (without releasing it yet) on -the specified element. - - - - - -an element locator - -the value to type - -Sets the value of an input field, as though you typed it in. - -

    Can also be used to set the value of combo boxes, check boxes, etc. In these cases, -value should be the value of the option selected, not the visible text.

    - -
    - - - -an element locator - -the value to type - -Simulates keystroke events on the specified element, as though you typed the value key-by-key. - -

    This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string; -this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.

    - -

    Unlike the simple "type" command, which forces the specified value into the page directly, this command -may or may not have any visible effect, even in cases where typing keys would normally have a visible effect. -For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in -the field.

    -

    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 -send the keystroke events corresponding to what you just typed.

    - -
    - - - -the number of milliseconds to pause after operation - -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., -the delay is 0 milliseconds. - - - - - -the execution speed in milliseconds. - -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., -the delay is 0 milliseconds. - -See also setSpeed. - - - - - -an element locator - -Check a toggle-button (checkbox/radio) - - - - - -an element locator - -Uncheck a toggle-button (checkbox/radio) - - - - - -an element locator identifying a drop-down menu - -an option locator (a label by default) - -Select an option from a drop-down using an option locator. - -

    -Option locators provide different ways of specifying options of an HTML -Select element (e.g. for selecting a specific option, or for asserting -that the selected option satisfies a specification). There are several -forms of Select Option Locator. -

    -
      -
    • label=labelPattern: -matches options based on their labels, i.e. the visible text. (This -is the default.) -
        -
      • label=regexp:^[Oo]ther
      • -
      -
    • -
    • value=valuePattern: -matches options based on their values. -
        -
      • value=other
      • -
      - - -
    • -
    • id=id: - -matches options based on their ids. -
        -
      • id=option1
      • -
      -
    • -
    • index=index: -matches an option based on its index (offset from zero). -
        - -
      • index=2
      • -
      -
    • -
    -

    -If no option locator prefix is provided, the default behaviour is to match on label. -

    - -
    - - - -an element locator identifying a multi-select box - -an option locator (a label by default) - -Add a selection to the set of selected options in a multi-select element using an option locator. - -@see #doSelect for details of option locators - - - - - -an element locator identifying a multi-select box - -an option locator (a label by default) - -Remove a selection from the set of selected options in a multi-select element using an option locator. - -@see #doSelect for details of option locators - - - - - -an element locator identifying a multi-select box - -Unselects all of the selected options in a multi-select element. - - - - - -an element locator for the form you want to submit - -Submit the specified form. This is particularly useful for forms without -submit buttons, e.g. single-input "Search" forms. - - - - - -the URL to open; may be relative or absolute - -Opens an URL in the test frame. This accepts both relative and absolute -URLs. - -The "open" command waits for the page to load before proceeding, -ie. the "AndWait" suffix is implicit. - -Note: The URL must be on the same domain as the runner HTML -due to security restrictions in the browser (Same Origin Policy). If you -need to open an URL on another domain, use the Selenium Server to start a -new browser session on that domain. - - - - - -the URL to open, which can be blank - -the JavaScript window ID of the window to select - -Opens a popup window (if a window with that ID isn't already open). -After opening the window, you'll need to select it using the selectWindow -command. - -

    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). -In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using -an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - -
    - - - -the JavaScript window ID of the window to select - -Selects a popup window using a window locator; once a popup window has been selected, all -commands go to that window. To select the main window again, use null -as the target. - -

    - -Window locators provide different ways of specifying the window object: -by title, by internal JavaScript "name," or by JavaScript variable. -

    -
      -
    • title=My Special Window: -Finds the window using the text that appears in the title bar. Be careful; -two windows can share the same title. If that happens, this locator will -just pick one. -
    • -
    • name=myWindow: -Finds the window using its internal JavaScript "name" property. This is the second -parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag) -(which Selenium intercepts). -
    • -
    • var=variableName: -Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current -application window, e.g. "window.foo = window.open(url);". In those cases, you can open the window using -"var=foo". -
    • -
    -

    -If no window locator prefix is provided, we'll try to guess what you mean like this:

    -

    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).

    -

    2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed -that this variable contains the return value from a call to the JavaScript window.open() method.

    -

    3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".

    -

    4.) If that fails, we'll try looping over all of the known windows to try to find the appropriate "title". -Since "title" is not necessarily unique, this may have unexpected behavior.

    - -

    If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages -which identify the names of windows created via window.open (and therefore intercepted by Selenium). You will see messages -like the following for each window as it is opened:

    - -

    debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"

    - -

    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). -(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 -an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - -
    - - - -an element locator identifying a frame or iframe - -Selects a frame within the current window. (You may invoke this command -multiple times to select nested frames.) To select the parent frame, use -"relative=parent" as a locator; to select the top frame, use "relative=top". -You can also select a frame by its 0-based index number; select the first frame with -"index=0", or the third frame with "index=2". - -

    You may also use a DOM expression to identify the frame you want directly, -like this: dom=frames["main"].frames["subframe"]

    - -
    - - - -true if the new frame is this code's window - -starting frame - -new frame (which might be relative to the current one) - -Determine whether current/locator identify the frame containing this running code. - -

    This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to identify -the "current" frame. In this case, when the test calls selectFrame, this -routine is called for each frame to figure out which one has been selected. -The selected frame will return true, while all others will return false.

    - -
    - - - -true if the new window is this code's window - -starting window - -new window (which might be relative to the current one, e.g., "_parent") - -Determine whether currentWindowString plus target identify the window containing this running code. - -

    This is useful in proxy injection mode, where this code runs in every -browser frame and window, and sometimes the selenium server needs to identify -the "current" window. In this case, when the test calls selectWindow, this -routine is called for each window to figure out which one has been selected. -The selected window will return true, while all others will return false.

    - -
    - - - -the JavaScript window "name" of the window that will appear (not the text of the title bar) - -a timeout in milliseconds, after which the action will return with an error - -Waits for a popup window to appear and load up. - - - - - -

    -By default, Selenium's overridden window.confirm() function will -return true, as if the user had manually clicked OK; after running -this command, the next call to confirm() will return false, as if -the user had clicked Cancel. Selenium will then resume using the -default behavior for future confirmations, automatically returning -true (OK) unless/until you explicitly call this command for each -confirmation. -

    -

    -Take note - every time a confirmation comes up, you must -consume it with a corresponding getConfirmation, or else -the next selenium operation will fail. -

    - -
    - - - -

    -Undo the effect of calling chooseCancelOnNextConfirmation. Note -that Selenium's overridden window.confirm() function will normally automatically -return true, as if the user had manually clicked OK, so you shouldn't -need to use this command unless for some reason you need to change -your mind prior to the next confirmation. After any confirmation, Selenium will resume using the -default behavior for future confirmations, automatically returning -true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each -confirmation. -

    -

    -Take note - every time a confirmation comes up, you must -consume it with a corresponding getConfirmation, or else -the next selenium operation will fail. -

    - -
    - - - -the answer to give in response to the prompt pop-up - -Instructs Selenium to return the specified answer string in response to -the next JavaScript prompt [window.prompt()]. - - - - - -Simulates the user clicking the "back" button on their browser. - - - - - -Simulates the user clicking the "Refresh" button on their browser. - - - - - -Simulates the user clicking the "close" button in the titlebar of a popup -window or tab. - - - - - -true if there is an alert - -Has an alert occurred? - -

    -This function never throws an exception -

    - -
    - - - -true if there is a pending prompt - -Has a prompt occurred? - -

    -This function never throws an exception -

    - -
    - - - -true if there is a pending confirmation - -Has confirm() been called? - -

    -This function never throws an exception -

    - -
    - - - -The message of the most recent JavaScript alert - -Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts. - -

    Getting an alert has the same effect as manually clicking OK. If an -alert is generated but you do not consume it with getAlert, the next Selenium action -will fail.

    - -

    Under Selenium, JavaScript alerts will NOT pop up a visible alert -dialog.

    - -

    Selenium does NOT support JavaScript alerts that are generated in a -page's onload() event handler. In this case a visible dialog WILL be -generated and Selenium will hang until someone manually clicks OK.

    - -
    - - - -the message of the most recent JavaScript confirmation dialog - -Retrieves the message of a JavaScript confirmation dialog generated during -the previous action. - -

    -By default, the confirm function will return true, having the same effect -as manually clicking OK. This can be changed by prior execution of the -chooseCancelOnNextConfirmation command. -

    -

    -If an confirmation is generated but you do not consume it with getConfirmation, -the next Selenium action will fail. -

    - -

    -NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible -dialog. -

    - -

    -NOTE: Selenium does NOT support JavaScript confirmations that are -generated in a page's onload() event handler. In this case a visible -dialog WILL be generated and Selenium will hang until you manually click -OK. -

    - -
    - - - -the message of the most recent JavaScript question prompt - -Retrieves the message of a JavaScript question prompt dialog generated during -the previous action. - -

    Successful handling of the prompt requires prior execution of the -answerOnNextPrompt command. If a prompt is generated but you -do not get/verify it, the next Selenium action will fail.

    - -

    NOTE: under Selenium, JavaScript prompts will NOT pop up a visible -dialog.

    - -

    NOTE: Selenium does NOT support JavaScript prompts that are generated in a -page's onload() event handler. In this case a visible dialog WILL be -generated and Selenium will hang until someone manually clicks OK.

    - -
    - - - -the absolute URL of the current page - -Gets the absolute URL of the current page. - - - - - -the title of the current page - -Gets the title of the current page. - - - - - -the entire text of the page - -Gets the entire text of the page. - - - - - -the element value, or "on/off" for checkbox/radio elements - -an element locator - -Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter). -For checkbox/radio elements, the value will be "on" or "off" depending on -whether the element is checked or not. - - - - - -the text of the element - -an element locator - -Gets the text of an element. This works for any element that contains -text. This command uses either the textContent (Mozilla-like browsers) or -the innerText (IE-like browsers) of the element, which is the rendered -text shown to the user. - - - - - -an element locator - -Briefly changes the backgroundColor of the specified element yellow. Useful for debugging. - - - - - -the results of evaluating the snippet - -the JavaScript snippet to run - -Gets the result of evaluating the specified JavaScript snippet. The snippet may -have multiple lines, but only the result of the last line will be returned. - -

    Note that, by default, the snippet will run in the context of the "selenium" -object itself, so this will refer to the Selenium object. Use window to -refer to the window of your application, e.g. window.document.getElementById('foo')

    - -

    If you need to use -a locator to refer to a single element in your application page, you can -use this.browserbot.findElement("id=foo") where "id=foo" is your locator.

    - -
    - - - -true if the checkbox is checked, false otherwise - -an element locator pointing to a checkbox or radio button - -Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button. - - - - - -the text from the specified cell - -a cell address, e.g. "foo.1.4" - -Gets the text from a cell of a table. The cellAddress syntax -tableLocator.row.column, where row and column start at 0. - - - - - -an array of all selected option labels in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option labels (visible text) for selected options in the specified select or multi-select element. - - - - - -the selected option label in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option label (visible text) for selected option in the specified select element. - - - - - -an array of all selected option values in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option values (value attributes) for selected options in the specified select or multi-select element. - - - - - -the selected option value in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option value (value attribute) for selected option in the specified select element. - - - - - -an array of all selected option indexes in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element. - - - - - -the selected option index in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option index (option number, starting at 0) for selected option in the specified select element. - - - - - -an array of all selected option IDs in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option element IDs for selected options in the specified select or multi-select element. - - - - - -the selected option ID in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets option element ID for selected option in the specified select element. - - - - - -true if some option has been selected, false otherwise - -an element locator identifying a drop-down menu - -Determines whether some option in a drop-down menu is selected. - - - - - -an array of all option labels in the specified select drop-down - -an element locator identifying a drop-down menu - -Gets all option labels in the specified select drop-down. - - - - - -the value of the specified attribute - -an element locator followed by an @ sign and then the name of the attribute, e.g. "foo@bar" - -Gets the value of an element attribute. The value of the attribute may -differ across browsers (this is the case for the "style" attribute, for -example). - - - - - -true if the pattern matches the text, false otherwise - -a pattern to match with the text of the page - -Verifies that the specified text pattern appears somewhere on the rendered page shown to the user. - - - - - -true if the element is present, false otherwise - -an element locator - -Verifies that the specified element is somewhere on the page. - - - - - -true if the specified element is visible, false otherwise - -an element locator - -Determines if the specified element is visible. An -element can be rendered invisible by setting the CSS "visibility" -property to "hidden", or the "display" property to "none", either for the -element itself or one if its ancestors. This method will fail if -the element is not present. - - - - - -true if the input element is editable, false otherwise - -an element locator - -Determines whether the specified input element is editable, ie hasn't been disabled. -This method will fail if the specified element isn't an input element. - - - - - -the IDs of all buttons on the page - -Returns the IDs of all buttons on the page. - -

    If a given button has no ID, it will appear as "" in this array.

    - -
    - - - -the IDs of all links on the page - -Returns the IDs of all links on the page. - -

    If a given link has no ID, it will appear as "" in this array.

    - -
    - - - -the IDs of all field on the page - -Returns the IDs of all input fields on the page. - -

    If a given field has no ID, it will appear as "" in this array.

    - -
    - - - -the set of values of this attribute from all known windows. - -name of an attribute on the windows - -Returns every instance of some attribute from all known windows. - - - - - -an element locator - -offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - -deprecated - use dragAndDrop instead - - - - - -the number of pixels between "mousemove" events - -Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10). -

    Setting this value to 0 means that we'll send a "mousemove" event to every single pixel -in between the start location and the end location; that can be very slow, and may -cause some browsers to force the JavaScript to timeout.

    - -

    If the mouse speed is greater than the distance between the two dragged objects, we'll -just send one "mousemove" at the start location and then one final one at the end location.

    - -
    - - - -the number of pixels between "mousemove" events during dragAndDrop commands (default=10) - -Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10). - - - - - -an element locator - -offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - -Drags an element a certain distance and then drops it - - - - - -an element to be dragged - -an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged is dropped - -Drags an element and drops it on another element - - - - - -Gives focus to the currently selected window - - - - - -Resize currently selected window to take up the entire screen - - - - - -the IDs of all windows that the browser knows about. - -Returns the IDs of all windows that the browser knows about. - - - - - -the names of all windows that the browser knows about. - -Returns the names of all windows that the browser knows about. - - - - - -the titles of all windows that the browser knows about. - -Returns the titles of all windows that the browser knows about. - - - - - -the entire HTML source - -Returns the entire HTML source between the opening and -closing "html" tags. - - - - - -an element locator pointing to an input element or textarea - -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. - -Moves the text cursor to the specified position in the given input element or textarea. -This method will fail if the specified element isn't an input element or textarea. - - - - - -of relative index of the element to its parent (starting from 0) - -an element locator pointing to an element - -Get the relative index of an element to its parent (starting from 0). The comment node and empty text node -will be ignored. - - - - - -true if element1 is the previous sibling of element2, false otherwise - -an element locator pointing to the first element - -an element locator pointing to the second element - -Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will -not be considered ordered. - - - - - -of pixels from the edge of the frame. - -an element locator pointing to an element OR an element itself - -Retrieves the horizontal position of an element - - - - - -of pixels from the edge of the frame. - -an element locator pointing to an element OR an element itself - -Retrieves the vertical position of an element - - - - - -width of an element in pixels - -an element locator pointing to an element - -Retrieves the width of an element - - - - - -height of an element in pixels - -an element locator pointing to an element - -Retrieves the height of an element - - - - - -the numerical position of the cursor in the field - -an element locator pointing to an input element or textarea - -Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers. - -

    Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to -return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as SEL-243.

    -This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.
    - -
    - - - -the value passed in - -the value to return - -Returns the specified expression. - -

    This is useful because of JavaScript preprocessing. -It is used to generate commands like assertExpression and waitForExpression.

    - -
    - - - -the number of nodes that match the specified xpath - -the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you. - -Returns the number of nodes that match the specified xpath, eg. "//table" would give -the number of tables. - - - - - -an element locator pointing to an element - -a string to be used as the ID of the specified element - -Temporarily sets the "id" attribute of the specified element, so you can locate it in the future -using its ID rather than a slow/complicated XPath. This ID will disappear once the page is -reloaded. - - - - - -boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath - -Specifies whether Selenium should use the native in-browser implementation -of XPath (if any native version is available); if you pass "false" to -this function, we will always use our pure-JavaScript xpath library. -Using the pure-JS xpath library can improve the consistency of xpath -element locators between different browser vendors, but the pure-JS -version is much slower than the native implementations. - - - - - -boolean, true means we'll ignore attributes without value at the expense of xpath "correctness"; false means we'll sacrifice speed for correctness. - -Specifies whether Selenium will ignore xpath attributes that have no -value, i.e. are the empty string, when using the non-native xpath -evaluation engine. You'd want to do this for performance reasons in IE. -However, this could break certain xpaths, for example an xpath that looks -for an attribute whose value is NOT the empty string. - -The hope is that such xpaths are relatively rare, but the user should -have the option of using them. Note that this only influences xpath -evaluation when using the ajaxslt engine (i.e. not "javascript-xpath"). - - - - - -the JavaScript snippet to run - -a timeout in milliseconds, after which this command will return with an error - -Runs the specified JavaScript snippet repeatedly until it evaluates to "true". -The snippet may have multiple lines, but only the result of the last line -will be considered. - -

    Note that, by default, the snippet will be run in the runner's test window, not in the window -of your application. To get the window of your application, you can use -the JavaScript snippet selenium.browserbot.getCurrentWindow(), and then -run your JavaScript in there

    - -
    - - - -a timeout in milliseconds, after which the action will return with an error - -Specifies the amount of time that Selenium will wait for actions to complete. - -

    Actions that require waiting include "open" and the "waitFor*" actions.

    -The default timeout is 30 seconds.
    - -
    - - - -a timeout in milliseconds, after which this command will return with an error - -Waits for a new page to load. - -

    You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc. -(which are only available in the JS API).

    - -

    Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded" -flag when it first notices a page load. Running any other Selenium command after -turns the flag to false. Hence, if you want to wait for a page to load, you must -wait immediately after a Selenium command that caused a page-load.

    - -
    - - - -FrameAddress from the server side - -a timeout in milliseconds, after which this command will return with an error - -Waits for a new frame to load. - -

    Selenium constantly keeps track of new pages and frames loading, -and sets a "newPageLoaded" flag when it first notices a page load.

    - -See waitForPageToLoad for more information.
    - -
    - - - -all cookies of the current page under test - -Return all cookies of the current page under test. - - - - - -the value of the cookie - -the name of the cookie - -Returns the value of the cookie with the specified name, or throws an error if the cookie is not present. - - - - - -true if a cookie with the specified name is present, or false otherwise. - -the name of the cookie - -Returns true if a cookie with the specified name is present, or false otherwise. - - - - - -name and value of the cookie in a format "name=value" - -options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'. the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will usually fail. - -Create a new cookie whose path and domain are same with those of current page -under test, unless you specified a path for this cookie explicitly. - - - - - -the name of the cookie to be deleted - -options for the cookie. Currently supported options include 'path', 'domain' and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". The order of options are irrelevant. Note that specifying a domain that isn't a subset of the current domain will usually fail. - -Delete a named cookie with specified path and domain. Be careful; to delete a cookie, you -need to delete it using the exact same path and domain that were used to create the cookie. -If the path is wrong, or the domain is wrong, the cookie simply won't be deleted. Also -note that specifying a domain that isn't a subset of the current domain will usually fail. - -Since there's no way to discover at runtime the original path and domain of a given cookie, -we've added an option called 'recurse' to try all sub-domains of the current domain with -all paths that are a subset of the current path. Beware; this option can be slow. In -big-O notation, it operates in O(n*m) time, where n is the number of dots in the domain -name and m is the number of slashes in the path. - - - - - -Calls deleteCookie with recurse=true on all cookies visible to the current page. -As noted on the documentation for deleteCookie, recurse=true can be much slower -than simply deleting the cookies using a known domain/path. - - - - - -one of the following: "debug", "info", "warn", "error" or "off" - -Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded. -Valid logLevel strings are: "debug", "info", "warn", "error" or "off". -To see the browser logs, you need to -either show the log window in GUI mode, or enable browser-side logging in Selenium RC. - - - - - -the JavaScript snippet to run - -Creates a new "script" tag in the body of the current test window, and -adds the specified text into the body of the command. Scripts run in -this way can often be debugged more easily than scripts executed using -Selenium's "getEval" command. Beware that JS exceptions thrown in these script -tags aren't managed by Selenium, so you should probably wrap your script -in try/catch blocks if there is any chance that the script will throw -an exception. - - - - - -the name of the strategy to define; this should use only letters [a-zA-Z] with no spaces or other punctuation. - -a string defining the body of a function in JavaScript. For example: return inDocument.getElementById(locator); - -Defines a new function for Selenium to locate elements on the page. -For example, -if you define the strategy "foo", and someone runs click("foo=blah"), we'll -run your function, passing you the string "blah", and click on the element -that your function -returns, or throw an "Element not found" error if your function returns null. - -We'll pass three arguments to your function: -
      -
    • locator: the string the user passed in
    • -
    • inWindow: the currently selected window
    • -
    • inDocument: the currently selected document
    • -
    -The function must return null if the element can't be found.
    - -
    - - - -the path to the file to persist the screenshot as. No filename extension will be appended by default. Directories will not be created if they do not exist, and an exception will be thrown, possibly by native code. - -a kwargs string that modifies the way the screenshot is captured. Example: "background=#CCFFDD" . Currently valid options:
    background
    the background CSS for the HTML document. This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed (possibly obscuring black text).
    - -Saves the entire contents of the current window canvas to a PNG file. -Contrast this with the captureScreenshot command, which captures the -contents of the OS viewport (i.e. whatever is currently being displayed -on the monitor), and is implemented in the RC only. Currently this only -works in Firefox when running in chrome mode, and in IE non-HTA using -the EXPERIMENTAL "Snapsie" utility. The Firefox implementation is mostly -borrowed from the Screengrab! Firefox extension. Please see -http://www.screengrab.org and http://snapsie.sourceforge.net/ for -details. - -
    - - - -the name of the rollup command - -keyword arguments string that influences how the rollup expands into commands - -Executes a command rollup, which is a series of commands with a unique -name, and optionally arguments that control the generation of the set of -commands. If any one of the rolled-up commands fails, the rollup is -considered to have failed. Rollups may also contain nested rollups. - - - - - -the Javascript content of the script to add - -(optional) the id of the new script tag. If specified, and an element with this id already exists, this operation will fail. - -Loads script content into a new script tag in the Selenium document. This -differs from the runScript command in that runScript adds the script tag -to the document of the AUT, not the Selenium document. The following -entities in the script content are replaced by the characters they -represent: - - < - > - & - -The corresponding remove command is removeScript. - - - - - -the id of the script element to remove. - -Removes a script tag from the Selenium document identified by the given -id. Does nothing if the referenced tag doesn't exist. - - - - - -name of the desired library Only the following three can be chosen: ajaxslt - Google's library javascript - Cybozu Labs' faster library default - The default library. Currently the default library is ajaxslt. If libraryName isn't one of these three, then no change will be made. - -Allows choice of one of the available libraries. - - - - - -the message to be sent to the browser - -Writes a message to the status bar and adds a note to the browser-side -log. - - - - - -an element locator - -a URL pointing to the specified file. Before the file can be set in the input field (fieldLocator), Selenium RC may need to transfer the file to the local machine before attaching the file in a web page form. This is common in selenium grid configurations where the RC server driving the browser is not the same machine that started the test. Supported Browsers: Firefox ("*chrome") only. - -Sets a file input (upload) field to the file listed in fileLocator - - - - - -the absolute path to the file to be written, e.g. "c:\blah\screenshot.png" - -Captures a PNG screenshot to the specified file. - - - - - -The base 64 encoded string of the screen shot (PNG file) - -Capture a PNG screenshot. It then returns the file as a base 64 encoded string. - - - - - -The base 64 encoded string of the page screenshot (PNG file) - -A kwargs string that modifies the way the screenshot is captured. Example: "background=#CCFFDD". This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed (possibly obscuring black text). - -Downloads a screenshot of the browser current window canvas to a -based 64 encoded PNG file. The entire windows canvas is captured, -including parts rendered outside of the current view port. - -Currently this only works in Mozilla and when running in chrome mode. - - - - - -Kills the running Selenium Server and all browser sessions. After you run this command, you will no longer be able to send -commands to the server; you can't remotely start the server once it has been stopped. Normally -you should prefer to run the "stop" command, which terminates the current browser session, rather than -shutting down the entire server. - - - - - -The last N log messages as a multi-line string. - -Retrieve the last messages logged on a specific remote control. Useful for error reports, especially -when running multiple remote controls in a distributed environment. The maximum number of log messages -that can be retrieve is configured on remote control startup. - - - - - -an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - -Simulates a user pressing a key (without releasing it yet) by sending a native operating system keystroke. -This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing -a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and -metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular -element, focus on the element first before running this command. - - - - - -an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - -Simulates a user releasing a key by sending a native operating system keystroke. -This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing -a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and -metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular -element, focus on the element first before running this command. - - - - - -an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - -Simulates a user pressing and releasing a key by sending a native operating system keystroke. -This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing -a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and -metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular -element, focus on the element first before running this command. - - - -
    diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/cssQuery-p.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/cssQuery-p.js deleted file mode 100644 index 4a7eb88a..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/cssQuery-p.js +++ /dev/null @@ -1,6 +0,0 @@ -/* - cssQuery, version 2.0.2 (2005-08-19) - Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) - License: http://creativecommons.org/licenses/LGPL/2.1/ -*/ -eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 x=6(){7 1D="2.0.2";7 C=/\\s*,\\s*/;7 x=6(s,A){33{7 m=[];7 u=1z.32.2c&&!A;7 b=(A)?(A.31==22)?A:[A]:[1g];7 1E=18(s).1l(C),i;9(i=0;i<1E.y;i++){s=1y(1E[i]);8(U&&s.Z(0,3).2b("")==" *#"){s=s.Z(2);A=24([],b,s[1])}1A A=b;7 j=0,t,f,a,c="";H(j+~]/;7 20=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1y(s){8(S.l(s))s=" "+s;5 s.P(20)||[]};7 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;7 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;7 18=6(s){5 s.O(W,"$1").O(I,"$1*$2")};7 1u={1Z:6(){5"\'"},P:/^(\'[^\']*\')|("[^"]*")$/,l:6(s){5 o.P.l(s)},1S:6(s){5 o.l(s)?s:o+s+o},1Y:6(s){5 o.l(s)?s.Z(1,-1):s}};7 1s=6(t){5 1u.1Y(t)};7 E=/([\\/()[\\]?{}|*+-])/g;6 R(s){5 s.O(E,"\\\\$1")};x.15("1j-2H",6(){D[">"]=6(r,f,t,n){7 e,i,j;9(i=0;i=c);5(c%m)==s}});x.15("1j-2m",6(){U=1i("L;/*@2l@8(@\\2k)U=K@2j@*/");8(!U){X=6(e,t,n){5 n?e.2i("*",t):e.X(t)};14=6(e,n){5!n||(n=="*")||(e.2h==n)};1h=1g.1I?6(e){5/1J/i.l(Q(e).1I)}:6(e){5 Q(e).1H.1f!="2g"};1e=6(e){5 e.2f||e.1G||1b(e)};6 1b(e){7 t="",n,i;9(i=0;(n=e.1F[i]);i++){1d(n.1c){F 11:F 1:t+=1b(n);1a;F 3:t+=n.2e;1a}}5 t}}});19=K;5 x}();',62,190,'|||||return|function|var|if|for||||||||pseudoClasses||||test|||this||AttributeSelector|||||||cssQuery|length|push|fr|id||selectors||case|nextElementSibling|while||tests|true|false|thisElement||replace|match|getDocument|regEscape||attributeSelectors|isMSIE|cache||getElementsByTagName|isNaN|slice|child||new|getAttribute|compareNamespace|addModule|previousElementSibling|compareTagName|parseSelector|loaded|break|_0|nodeType|switch|getTextContent|tagName|document|isXML|eval|css|_1|split|ch|parentNode|childElements|nthChild|disabled|firstElementChild|getText|RegExp|Quote|x22|PREFIX|lang|_2|arguments|else|all|links|version|se|childNodes|innerText|documentElement|contentType|xml|parseInt|indeterminate|checked|last|nth|lastElementChild|parse|_3|add|href|String|className|create|NS_IE|remove|toString|ST|select|Array|null|_4|mimeType|lastChild|firstChild|continue|modules|delete|join|caching|error|nodeValue|textContent|HTML|prefix|getElementsByTagNameNS|end|x5fwin32|cc_on|standard||odd|even|enabled|hash|location|target|not|only|empty|root|contains|level3|outerHTML|htmlFor|class|toLowerCase|Function|name|first|level2|prototype|item|scopeName|toUpperCase|ownerDocument|Document|XML|Boolean|URL|unknown|typeof|nextSibling|previousSibling|visited|link|valueOf|clearCache|catch|concat|constructor|callee|try'.split('|'),0,{})) diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level2.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level2.js deleted file mode 100644 index 02dd0e5f..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level2.js +++ /dev/null @@ -1,142 +0,0 @@ -/* - cssQuery, version 2.0.2 (2005-08-19) - Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) - License: http://creativecommons.org/licenses/LGPL/2.1/ -*/ - -cssQuery.addModule("css-level2", function() { - -// ----------------------------------------------------------------------- -// selectors -// ----------------------------------------------------------------------- - -// child selector -selectors[">"] = function($results, $from, $tagName, $namespace) { - var $element, i, j; - for (i = 0; i < $from.length; i++) { - var $subset = childElements($from[i]); - for (j = 0; ($element = $subset[j]); j++) - if (compareTagName($element, $tagName, $namespace)) - $results.push($element); - } -}; - -// sibling selector -selectors["+"] = function($results, $from, $tagName, $namespace) { - for (var i = 0; i < $from.length; i++) { - var $element = nextElementSibling($from[i]); - if ($element && compareTagName($element, $tagName, $namespace)) - $results.push($element); - } -}; - -// attribute selector -selectors["@"] = function($results, $from, $attributeSelectorID) { - var $test = attributeSelectors[$attributeSelectorID].test; - var $element, i; - for (i = 0; ($element = $from[i]); i++) - if ($test($element)) $results.push($element); -}; - -// ----------------------------------------------------------------------- -// pseudo-classes -// ----------------------------------------------------------------------- - -pseudoClasses["first-child"] = function($element) { - return !previousElementSibling($element); -}; - -pseudoClasses["lang"] = function($element, $code) { - $code = new RegExp("^" + $code, "i"); - while ($element && !$element.getAttribute("lang")) $element = $element.parentNode; - return $element && $code.test($element.getAttribute("lang")); -}; - -// ----------------------------------------------------------------------- -// attribute selectors -// ----------------------------------------------------------------------- - -// constants -AttributeSelector.NS_IE = /\\:/g; -AttributeSelector.PREFIX = "@"; -// properties -AttributeSelector.tests = {}; -// methods -AttributeSelector.replace = function($match, $attribute, $namespace, $compare, $value) { - var $key = this.PREFIX + $match; - if (!attributeSelectors[$key]) { - $attribute = this.create($attribute, $compare || "", $value || ""); - // store the selector - attributeSelectors[$key] = $attribute; - attributeSelectors.push($attribute); - } - return attributeSelectors[$key].id; -}; -AttributeSelector.parse = function($selector) { - $selector = $selector.replace(this.NS_IE, "|"); - var $match; - while ($match = $selector.match(this.match)) { - var $replace = this.replace($match[0], $match[1], $match[2], $match[3], $match[4]); - $selector = $selector.replace(this.match, $replace); - } - return $selector; -}; -AttributeSelector.create = function($propertyName, $test, $value) { - var $attributeSelector = {}; - $attributeSelector.id = this.PREFIX + attributeSelectors.length; - $attributeSelector.name = $propertyName; - $test = this.tests[$test]; - $test = $test ? $test(this.getAttribute($propertyName), getText($value)) : false; - $attributeSelector.test = new Function("e", "return " + $test); - return $attributeSelector; -}; -AttributeSelector.getAttribute = function($name) { - switch ($name.toLowerCase()) { - case "id": - return "e.id"; - case "class": - return "e.className"; - case "for": - return "e.htmlFor"; - case "href": - if (isMSIE) { - // IE always returns the full path not the fragment in the href attribute - // so we RegExp it out of outerHTML. Opera does the same thing but there - // is no way to get the original attribute. - return "String((e.outerHTML.match(/href=\\x22?([^\\s\\x22]*)\\x22?/)||[])[1]||'')"; - } - } - return "e.getAttribute('" + $name.replace($NAMESPACE, ":") + "')"; -}; - -// ----------------------------------------------------------------------- -// attribute selector tests -// ----------------------------------------------------------------------- - -AttributeSelector.tests[""] = function($attribute) { - return $attribute; -}; - -AttributeSelector.tests["="] = function($attribute, $value) { - return $attribute + "==" + Quote.add($value); -}; - -AttributeSelector.tests["~="] = function($attribute, $value) { - return "/(^| )" + regEscape($value) + "( |$)/.test(" + $attribute + ")"; -}; - -AttributeSelector.tests["|="] = function($attribute, $value) { - return "/^" + regEscape($value) + "(-|$)/.test(" + $attribute + ")"; -}; - -// ----------------------------------------------------------------------- -// parsing -// ----------------------------------------------------------------------- - -// override parseSelector to parse out attribute selectors -var _parseSelector = parseSelector; -parseSelector = function($selector) { - return _parseSelector(AttributeSelector.parse($selector)); -}; - -}); // addModule diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level3.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level3.js deleted file mode 100644 index 11d19664..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level3.js +++ /dev/null @@ -1,150 +0,0 @@ -/* - cssQuery, version 2.0.2 (2005-08-19) - Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) - License: http://creativecommons.org/licenses/LGPL/2.1/ -*/ - -/* Thanks to Bill Edney */ - -cssQuery.addModule("css-level3", function() { - -// ----------------------------------------------------------------------- -// selectors -// ----------------------------------------------------------------------- - -// indirect sibling selector -selectors["~"] = function($results, $from, $tagName, $namespace) { - var $element, i; - for (i = 0; ($element = $from[i]); i++) { - while ($element = nextElementSibling($element)) { - if (compareTagName($element, $tagName, $namespace)) - $results.push($element); - } - } -}; - -// ----------------------------------------------------------------------- -// pseudo-classes -// ----------------------------------------------------------------------- - -// I'm hoping these pseudo-classes are pretty readable. Let me know if -// any need explanation. - -pseudoClasses["contains"] = function($element, $text) { - $text = new RegExp(regEscape(getText($text))); - return $text.test(getTextContent($element)); -}; - -pseudoClasses["root"] = function($element) { - return $element == getDocument($element).documentElement; -}; - -pseudoClasses["empty"] = function($element) { - var $node, i; - for (i = 0; ($node = $element.childNodes[i]); i++) { - if (thisElement($node) || $node.nodeType == 3) return false; - } - return true; -}; - -pseudoClasses["last-child"] = function($element) { - return !nextElementSibling($element); -}; - -pseudoClasses["only-child"] = function($element) { - $element = $element.parentNode; - return firstElementChild($element) == lastElementChild($element); -}; - -pseudoClasses["not"] = function($element, $selector) { - var $negated = cssQuery($selector, getDocument($element)); - for (var i = 0; i < $negated.length; i++) { - if ($negated[i] == $element) return false; - } - return true; -}; - -pseudoClasses["nth-child"] = function($element, $arguments) { - return nthChild($element, $arguments, previousElementSibling); -}; - -pseudoClasses["nth-last-child"] = function($element, $arguments) { - return nthChild($element, $arguments, nextElementSibling); -}; - -pseudoClasses["target"] = function($element) { - return $element.id == location.hash.slice(1); -}; - -// UI element states - -pseudoClasses["checked"] = function($element) { - return $element.checked; -}; - -pseudoClasses["enabled"] = function($element) { - return $element.disabled === false; -}; - -pseudoClasses["disabled"] = function($element) { - return $element.disabled; -}; - -pseudoClasses["indeterminate"] = function($element) { - return $element.indeterminate; -}; - -// ----------------------------------------------------------------------- -// attribute selector tests -// ----------------------------------------------------------------------- - -AttributeSelector.tests["^="] = function($attribute, $value) { - return "/^" + regEscape($value) + "/.test(" + $attribute + ")"; -}; - -AttributeSelector.tests["$="] = function($attribute, $value) { - return "/" + regEscape($value) + "$/.test(" + $attribute + ")"; -}; - -AttributeSelector.tests["*="] = function($attribute, $value) { - return "/" + regEscape($value) + "/.test(" + $attribute + ")"; -}; - -// ----------------------------------------------------------------------- -// nth child support (Bill Edney) -// ----------------------------------------------------------------------- - -function nthChild($element, $arguments, $traverse) { - switch ($arguments) { - case "n": return true; - case "even": $arguments = "2n"; break; - case "odd": $arguments = "2n+1"; - } - - var $$children = childElements($element.parentNode); - function _checkIndex($index) { - var $index = ($traverse == nextElementSibling) ? $$children.length - $index : $index - 1; - return $$children[$index] == $element; - }; - - // it was just a number (no "n") - if (!isNaN($arguments)) return _checkIndex($arguments); - - $arguments = $arguments.split("n"); - var $multiplier = parseInt($arguments[0]); - var $step = parseInt($arguments[1]); - - if ((isNaN($multiplier) || $multiplier == 1) && $step == 0) return true; - if ($multiplier == 0 && !isNaN($step)) return _checkIndex($step); - if (isNaN($step)) $step = 0; - - var $count = 1; - while ($element = $traverse($element)) $count++; - - if (isNaN($multiplier) || $multiplier == 1) - return ($traverse == nextElementSibling) ? ($count <= $step) : ($step >= $count); - - return ($count % $multiplier) == $step; -}; - -}); // addModule diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-standard.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-standard.js deleted file mode 100644 index 77314b86..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-standard.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - cssQuery, version 2.0.2 (2005-08-19) - Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) - License: http://creativecommons.org/licenses/LGPL/2.1/ -*/ - -cssQuery.addModule("css-standard", function() { // override IE optimisation - -// cssQuery was originally written as the CSS engine for IE7. It is -// optimised (in terms of size not speed) for IE so this module is -// provided separately to provide cross-browser support. - -// ----------------------------------------------------------------------- -// browser compatibility -// ----------------------------------------------------------------------- - -// sniff for Win32 Explorer -isMSIE = eval("false;/*@cc_on@if(@\x5fwin32)isMSIE=true@end@*/"); - -if (!isMSIE) { - getElementsByTagName = function($element, $tagName, $namespace) { - return $namespace ? $element.getElementsByTagNameNS("*", $tagName) : - $element.getElementsByTagName($tagName); - }; - - compareNamespace = function($element, $namespace) { - return !$namespace || ($namespace == "*") || ($element.prefix == $namespace); - }; - - isXML = document.contentType ? function($element) { - return /xml/i.test(getDocument($element).contentType); - } : function($element) { - return getDocument($element).documentElement.tagName != "HTML"; - }; - - getTextContent = function($element) { - // mozilla || opera || other - return $element.textContent || $element.innerText || _getTextContent($element); - }; - - function _getTextContent($element) { - var $textContent = "", $node, i; - for (i = 0; ($node = $element.childNodes[i]); i++) { - switch ($node.nodeType) { - case 11: // document fragment - case 1: $textContent += _getTextContent($node); break; - case 3: $textContent += $node.nodeValue; break; - } - } - return $textContent; - }; -} -}); // addModule diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery.js deleted file mode 100644 index 1fcab4a1..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery.js +++ /dev/null @@ -1,356 +0,0 @@ -/* - cssQuery, version 2.0.2 (2005-08-19) - Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) - License: http://creativecommons.org/licenses/LGPL/2.1/ -*/ - -// the following functions allow querying of the DOM using CSS selectors -var cssQuery = function() { -var version = "2.0.2"; - -// ----------------------------------------------------------------------- -// main query function -// ----------------------------------------------------------------------- - -var $COMMA = /\s*,\s*/; -var cssQuery = function($selector, $$from) { -try { - var $match = []; - var $useCache = arguments.callee.caching && !$$from; - var $base = ($$from) ? ($$from.constructor == Array) ? $$from : [$$from] : [document]; - // process comma separated selectors - var $$selectors = parseSelector($selector).split($COMMA), i; - for (i = 0; i < $$selectors.length; i++) { - // convert the selector to a stream - $selector = _toStream($$selectors[i]); - // faster chop if it starts with id (MSIE only) - if (isMSIE && $selector.slice(0, 3).join("") == " *#") { - $selector = $selector.slice(2); - $$from = _msie_selectById([], $base, $selector[1]); - } else $$from = $base; - // process the stream - var j = 0, $token, $filter, $arguments, $cacheSelector = ""; - while (j < $selector.length) { - $token = $selector[j++]; - $filter = $selector[j++]; - $cacheSelector += $token + $filter; - // some pseudo-classes allow arguments to be passed - // e.g. nth-child(even) - $arguments = ""; - if ($selector[j] == "(") { - while ($selector[j++] != ")" && j < $selector.length) { - $arguments += $selector[j]; - } - $arguments = $arguments.slice(0, -1); - $cacheSelector += "(" + $arguments + ")"; - } - // process a token/filter pair use cached results if possible - $$from = ($useCache && cache[$cacheSelector]) ? - cache[$cacheSelector] : select($$from, $token, $filter, $arguments); - if ($useCache) cache[$cacheSelector] = $$from; - } - $match = $match.concat($$from); - } - delete cssQuery.error; - return $match; -} catch ($error) { - cssQuery.error = $error; - return []; -}}; - -// ----------------------------------------------------------------------- -// public interface -// ----------------------------------------------------------------------- - -cssQuery.toString = function() { - return "function cssQuery() {\n [version " + version + "]\n}"; -}; - -// caching -var cache = {}; -cssQuery.caching = false; -cssQuery.clearCache = function($selector) { - if ($selector) { - $selector = _toStream($selector).join(""); - delete cache[$selector]; - } else cache = {}; -}; - -// allow extensions -var modules = {}; -var loaded = false; -cssQuery.addModule = function($name, $script) { - if (loaded) eval("$script=" + String($script)); - modules[$name] = new $script();; -}; - -// hackery -cssQuery.valueOf = function($code) { - return $code ? eval($code) : this; -}; - -// ----------------------------------------------------------------------- -// declarations -// ----------------------------------------------------------------------- - -var selectors = {}; -var pseudoClasses = {}; -// a safari bug means that these have to be declared here -var AttributeSelector = {match: /\[([\w-]+(\|[\w-]+)?)\s*(\W?=)?\s*([^\]]*)\]/}; -var attributeSelectors = []; - -// ----------------------------------------------------------------------- -// selectors -// ----------------------------------------------------------------------- - -// descendant selector -selectors[" "] = function($results, $from, $tagName, $namespace) { - // loop through current selection - var $element, i, j; - for (i = 0; i < $from.length; i++) { - // get descendants - var $subset = getElementsByTagName($from[i], $tagName, $namespace); - // loop through descendants and add to results selection - for (j = 0; ($element = $subset[j]); j++) { - if (thisElement($element) && compareNamespace($element, $namespace)) - $results.push($element); - } - } -}; - -// ID selector -selectors["#"] = function($results, $from, $id) { - // loop through current selection and check ID - var $element, j; - for (j = 0; ($element = $from[j]); j++) if ($element.id == $id) $results.push($element); -}; - -// class selector -selectors["."] = function($results, $from, $className) { - // create a RegExp version of the class - $className = new RegExp("(^|\\s)" + $className + "(\\s|$)"); - // loop through current selection and check class - var $element, i; - for (i = 0; ($element = $from[i]); i++) - if ($className.test($element.className)) $results.push($element); -}; - -// pseudo-class selector -selectors[":"] = function($results, $from, $pseudoClass, $arguments) { - // retrieve the cssQuery pseudo-class function - var $test = pseudoClasses[$pseudoClass], $element, i; - // loop through current selection and apply pseudo-class filter - if ($test) for (i = 0; ($element = $from[i]); i++) - // if the cssQuery pseudo-class function returns "true" add the element - if ($test($element, $arguments)) $results.push($element); -}; - -// ----------------------------------------------------------------------- -// pseudo-classes -// ----------------------------------------------------------------------- - -pseudoClasses["link"] = function($element) { - var $document = getDocument($element); - if ($document.links) for (var i = 0; i < $document.links.length; i++) { - if ($document.links[i] == $element) return true; - } -}; - -pseudoClasses["visited"] = function($element) { - // can't do this without jiggery-pokery -}; - -// ----------------------------------------------------------------------- -// DOM traversal -// ----------------------------------------------------------------------- - -// IE5/6 includes comments (LOL) in it's elements collections. -// so we have to check for this. the test is tagName != "!". LOL (again). -var thisElement = function($element) { - return ($element && $element.nodeType == 1 && $element.tagName != "!") ? $element : null; -}; - -// return the previous element to the supplied element -// previousSibling is not good enough as it might return a text or comment node -var previousElementSibling = function($element) { - while ($element && ($element = $element.previousSibling) && !thisElement($element)) continue; - return $element; -}; - -// return the next element to the supplied element -var nextElementSibling = function($element) { - while ($element && ($element = $element.nextSibling) && !thisElement($element)) continue; - return $element; -}; - -// return the first child ELEMENT of an element -// NOT the first child node (though they may be the same thing) -var firstElementChild = function($element) { - return thisElement($element.firstChild) || nextElementSibling($element.firstChild); -}; - -var lastElementChild = function($element) { - return thisElement($element.lastChild) || previousElementSibling($element.lastChild); -}; - -// return child elements of an element (not child nodes) -var childElements = function($element) { - var $childElements = []; - $element = firstElementChild($element); - while ($element) { - $childElements.push($element); - $element = nextElementSibling($element); - } - return $childElements; -}; - -// ----------------------------------------------------------------------- -// browser compatibility -// ----------------------------------------------------------------------- - -// all of the functions in this section can be overwritten. the default -// configuration is for IE. The functions below reflect this. standard -// methods are included in a separate module. It would probably be better -// the other way round of course but this makes it easier to keep IE7 trim. - -var isMSIE = true; - -var isXML = function($element) { - var $document = getDocument($element); - return (typeof $document.mimeType == "unknown") ? - /\.xml$/i.test($document.URL) : - Boolean($document.mimeType == "XML Document"); -}; - -// return the element's containing document -var getDocument = function($element) { - return $element.ownerDocument || $element.document; -}; - -var getElementsByTagName = function($element, $tagName) { - return ($tagName == "*" && $element.all) ? $element.all : $element.getElementsByTagName($tagName); -}; - -var compareTagName = function($element, $tagName, $namespace) { - if ($tagName == "*") return thisElement($element); - if (!compareNamespace($element, $namespace)) return false; - if (!isXML($element)) $tagName = $tagName.toUpperCase(); - return $element.tagName == $tagName; -}; - -var compareNamespace = function($element, $namespace) { - return !$namespace || ($namespace == "*") || ($element.scopeName == $namespace); -}; - -var getTextContent = function($element) { - return $element.innerText; -}; - -function _msie_selectById($results, $from, id) { - var $match, i, j; - for (i = 0; i < $from.length; i++) { - if ($match = $from[i].all.item(id)) { - if ($match.id == id) $results.push($match); - else if ($match.length != null) { - for (j = 0; j < $match.length; j++) { - if ($match[j].id == id) $results.push($match[j]); - } - } - } - } - return $results; -}; - -// for IE5.0 -if (![].push) Array.prototype.push = function() { - for (var i = 0; i < arguments.length; i++) { - this[this.length] = arguments[i]; - } - return this.length; -}; - -// ----------------------------------------------------------------------- -// query support -// ----------------------------------------------------------------------- - -// select a set of matching elements. -// "from" is an array of elements. -// "token" is a character representing the type of filter -// e.g. ">" means child selector -// "filter" represents the tag name, id or class name that is being selected -// the function returns an array of matching elements -var $NAMESPACE = /\|/; -function select($$from, $token, $filter, $arguments) { - if ($NAMESPACE.test($filter)) { - $filter = $filter.split($NAMESPACE); - $arguments = $filter[0]; - $filter = $filter[1]; - } - var $results = []; - if (selectors[$token]) { - selectors[$token]($results, $$from, $filter, $arguments); - } - return $results; -}; - -// ----------------------------------------------------------------------- -// parsing -// ----------------------------------------------------------------------- - -// convert css selectors to a stream of tokens and filters -// it's not a real stream. it's just an array of strings. -var $STANDARD_SELECT = /^[^\s>+~]/; -var $$STREAM = /[\s#.:>+~()@]|[^\s#.:>+~()@]+/g; -function _toStream($selector) { - if ($STANDARD_SELECT.test($selector)) $selector = " " + $selector; - return $selector.match($$STREAM) || []; -}; - -var $WHITESPACE = /\s*([\s>+~(),]|^|$)\s*/g; -var $IMPLIED_ALL = /([\s>+~,]|[^(]\+|^)([#.:@])/g; -var parseSelector = function($selector) { - return $selector - // trim whitespace - .replace($WHITESPACE, "$1") - // e.g. ".class1" --> "*.class1" - .replace($IMPLIED_ALL, "$1*$2"); -}; - -var Quote = { - toString: function() {return "'"}, - match: /^('[^']*')|("[^"]*")$/, - test: function($string) { - return this.match.test($string); - }, - add: function($string) { - return this.test($string) ? $string : this + $string + this; - }, - remove: function($string) { - return this.test($string) ? $string.slice(1, -1) : $string; - } -}; - -var getText = function($text) { - return Quote.remove($text); -}; - -var $ESCAPE = /([\/()[\]?{}|*+-])/g; -function regEscape($string) { - return $string.replace($ESCAPE, "\\$1"); -}; - -// ----------------------------------------------------------------------- -// modules -// ----------------------------------------------------------------------- - -// -------- >> insert modules here for packaging << -------- \\ - -loaded = true; - -// ----------------------------------------------------------------------- -// return the query function -// ----------------------------------------------------------------------- - -return cssQuery; - -}(); // cssQuery diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/prototype.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/prototype.js deleted file mode 100644 index 4453c4f5..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/prototype.js +++ /dev/null @@ -1,2006 +0,0 @@ -/* Prototype JavaScript framework, version 1.5.0_rc0 - * (c) 2005 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://prototype.conio.net/ - * -/*--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.5.0_rc0', - ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', - - emptyFunction: function() {}, - K: function(x) {return x} -} - -var Class = { - create: function() { - return function() { - this.initialize.apply(this, arguments); - } - } -} - -var Abstract = new Object(); - -Object.extend = function(destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; -} - -Object.inspect = function(object) { - try { - if (object == undefined) return 'undefined'; - if (object == null) return 'null'; - return object.inspect ? object.inspect() : object.toString(); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } -} - -Function.prototype.bind = function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } -} - -Function.prototype.bindAsEventListener = function(object) { - var __method = this; - return function(event) { - return __method.call(object, event || window.event); - } -} - -Object.extend(Number.prototype, { - toColorPart: function() { - var digits = this.toString(16); - if (this < 16) return '0' + digits; - return digits; - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - } -}); - -var Try = { - these: function() { - var returnValue; - - for (var i = 0; i < arguments.length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) {} - } - - return returnValue; - } -} - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create(); -PeriodicalExecuter.prototype = { - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.callback(); - } finally { - this.currentlyExecuting = false; - } - } - } -} -Object.extend(String.prototype, { - gsub: function(pattern, replacement) { - var result = '', source = this, match; - replacement = arguments.callee.prepareReplacement(replacement); - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += (replacement(match) || '').toString(); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - }, - - sub: function(pattern, replacement, count) { - replacement = this.gsub.prepareReplacement(replacement); - count = count === undefined ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - }, - - scan: function(pattern, iterator) { - this.gsub(pattern, iterator); - return this; - }, - - truncate: function(length, truncation) { - length = length || 30; - truncation = truncation === undefined ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : this; - }, - - strip: function() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }, - - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, - - stripScripts: function() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, - - extractScripts: function() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - }, - - evalScripts: function() { - return this.extractScripts().map(function(script) { return eval(script) }); - }, - - escapeHTML: function() { - var div = document.createElement('div'); - var text = document.createTextNode(this); - div.appendChild(text); - return div.innerHTML; - }, - - unescapeHTML: function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; - }, - - toQueryParams: function() { - var pairs = this.match(/^\??(.*)$/)[1].split('&'); - return pairs.inject({}, function(params, pairString) { - var pair = pairString.split('='); - params[pair[0]] = pair[1]; - return params; - }); - }, - - toArray: function() { - return this.split(''); - }, - - camelize: function() { - var oStringList = this.split('-'); - if (oStringList.length == 1) return oStringList[0]; - - var camelizedString = this.indexOf('-') == 0 - ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) - : oStringList[0]; - - for (var i = 1, len = oStringList.length; i < len; i++) { - var s = oStringList[i]; - camelizedString += s.charAt(0).toUpperCase() + s.substring(1); - } - - return camelizedString; - }, - - inspect: function() { - return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; - } -}); - -String.prototype.gsub.prepareReplacement = function(replacement) { - if (typeof replacement == 'function') return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; -} - -String.prototype.parseQuery = String.prototype.toQueryParams; - -var Template = Class.create(); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; -Template.prototype = { - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - return this.template.gsub(this.pattern, function(match) { - var before = match[1]; - if (before == '\\') return match[2]; - return before + (object[match[3]] || '').toString(); - }); - } -} - -var $break = new Object(); -var $continue = new Object(); - -var Enumerable = { - each: function(iterator) { - var index = 0; - try { - this._each(function(value) { - try { - iterator(value, index++); - } catch (e) { - if (e != $continue) throw e; - } - }); - } catch (e) { - if (e != $break) throw e; - } - }, - - all: function(iterator) { - var result = true; - this.each(function(value, index) { - result = result && !!(iterator || Prototype.K)(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator) { - var result = true; - this.each(function(value, index) { - if (result = !!(iterator || Prototype.K)(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator) { - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function (iterator) { - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator) { - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(pattern, iterator) { - var results = []; - this.each(function(value, index) { - var stringValue = value.toString(); - if (stringValue.match(pattern)) - results.push((iterator || Prototype.K)(value, index)); - }) - return results; - }, - - include: function(object) { - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inject: function(memo, iterator) { - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.collect(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (result == undefined || value >= result) - result = value; - }); - return result; - }, - - min: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (result == undefined || value < result) - result = value; - }); - return result; - }, - - partition: function(iterator) { - var trues = [], falses = []; - this.each(function(value, index) { - ((iterator || Prototype.K)(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value, index) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator) { - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator) { - return this.collect(function(value, index) { - return {value: value, criteria: iterator(value, index)}; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - }, - - toArray: function() { - return this.collect(Prototype.K); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (typeof args.last() == 'function') - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - }, - - inspect: function() { - return '#'; - } -} - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray -}); -var $A = Array.from = function(iterable) { - if (!iterable) return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i = 0; i < iterable.length; i++) - results.push(iterable[i]); - return results; - } -} - -Object.extend(Array.prototype, Enumerable); - -if (!Array.prototype._reverse) - Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0; i < this.length; i++) - iterator(this[i]); - }, - - clear: function() { - this.length = 0; - return this; - }, - - first: function() { - return this[0]; - }, - - last: function() { - return this[this.length - 1]; - }, - - compact: function() { - return this.select(function(value) { - return value != undefined || value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(value && value.constructor == Array ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - indexOf: function(object) { - for (var i = 0; i < this.length; i++) - if (this[i] == object) return i; - return -1; - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } -}); -var Hash = { - _each: function(iterator) { - for (var key in this) { - var value = this[key]; - if (typeof value == 'function') continue; - - var pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - merge: function(hash) { - return $H(hash).inject($H(this), function(mergedHash, pair) { - mergedHash[pair.key] = pair.value; - return mergedHash; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - return pair.map(encodeURIComponent).join('='); - }).join('&'); - }, - - inspect: function() { - return '#'; - } -} - -function $H(object) { - var hash = Object.extend({}, object || {}); - Object.extend(hash, Enumerable); - Object.extend(hash, Hash); - return hash; -} -ObjectRange = Class.create(); -Object.extend(ObjectRange.prototype, Enumerable); -Object.extend(ObjectRange.prototype, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - do { - iterator(value); - value = value.succ(); - } while (this.include(value)); - }, - - include: function(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } -}); - -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -} - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responderToAdd) { - if (!this.include(responderToAdd)) - this.responders.push(responderToAdd); - }, - - unregister: function(responderToRemove) { - this.responders = this.responders.without(responderToRemove); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (responder[callback] && typeof responder[callback] == 'function') { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) {} - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { - Ajax.activeRequestCount++; - }, - - onComplete: function() { - Ajax.activeRequestCount--; - } -}); - -Ajax.Base = function() {}; -Ajax.Base.prototype = { - setOptions: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - parameters: '' - } - Object.extend(this.options, options || {}); - }, - - responseIsSuccess: function() { - return this.transport.status == undefined - || this.transport.status == 0 - || (this.transport.status >= 200 && this.transport.status < 300); - }, - - responseIsFailure: function() { - return !this.responseIsSuccess(); - } -} - -Ajax.Request = Class.create(); -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Request.prototype = Object.extend(new Ajax.Base(), { - initialize: function(url, options) { - this.transport = Ajax.getTransport(); - this.setOptions(options); - this.request(url); - }, - - request: function(url) { - var parameters = this.options.parameters || ''; - if (parameters.length > 0) parameters += '&_='; - - try { - this.url = url; - if (this.options.method == 'get' && parameters.length > 0) - this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; - - Ajax.Responders.dispatch('onCreate', this, this.transport); - - this.transport.open(this.options.method, this.url, - this.options.asynchronous); - - if (this.options.asynchronous) { - this.transport.onreadystatechange = this.onStateChange.bind(this); - setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); - } - - this.setRequestHeaders(); - - var body = this.options.postBody ? this.options.postBody : parameters; - this.transport.send(this.options.method == 'post' ? body : null); - - } catch (e) { - this.dispatchException(e); - } - }, - - setRequestHeaders: function() { - var requestHeaders = - ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version, - 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; - - if (this.options.method == 'post') { - requestHeaders.push('Content-type', this.options.contentType); - - /* Force "Connection: close" for Mozilla browsers to work around - * a bug where XMLHttpReqeuest sends an incorrect Content-length - * header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType) - requestHeaders.push('Connection', 'close'); - } - - if (this.options.requestHeaders) - requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); - - for (var i = 0; i < requestHeaders.length; i += 2) - this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState != 1) - this.respondToReadyState(this.transport.readyState); - }, - - header: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) {} - }, - - evalJSON: function() { - try { - return eval('(' + this.header('X-JSON') + ')'); - } catch (e) {} - }, - - evalResponse: function() { - try { - return eval(this.transport.responseText); - } catch (e) { - this.dispatchException(e); - } - }, - - respondToReadyState: function(readyState) { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.evalJSON(); - - if (event == 'Complete') { - try { - (this.options['on' + this.transport.status] - || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(transport, json); - } catch (e) { - this.dispatchException(e); - } - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); - } - - try { - (this.options['on' + event] || Prototype.emptyFunction)(transport, json); - Ajax.Responders.dispatch('on' + event, this, transport, json); - } catch (e) { - this.dispatchException(e); - } - - /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ - if (event == 'Complete') - this.transport.onreadystatechange = Prototype.emptyFunction; - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Updater = Class.create(); - -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { - initialize: function(container, url, options) { - this.containers = { - success: container.success ? $(container.success) : $(container), - failure: container.failure ? $(container.failure) : - (container.success ? null : $(container)) - } - - this.transport = Ajax.getTransport(); - this.setOptions(options); - - var onComplete = this.options.onComplete || Prototype.emptyFunction; - this.options.onComplete = (function(transport, object) { - this.updateContent(); - onComplete(transport, object); - }).bind(this); - - this.request(url); - }, - - updateContent: function() { - var receiver = this.responseIsSuccess() ? - this.containers.success : this.containers.failure; - var response = this.transport.responseText; - - if (!this.options.evalScripts) - response = response.stripScripts(); - - if (receiver) { - if (this.options.insertion) { - new this.options.insertion(receiver, response); - } else { - Element.update(receiver, response); - } - } - - if (this.responseIsSuccess()) { - if (this.onComplete) - setTimeout(this.onComplete.bind(this), 10); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(); -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { - initialize: function(container, url, options) { - this.setOptions(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = {}; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(request) { - if (this.options.decay) { - this.decay = (request.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = request.responseText; - } - this.timer = setTimeout(this.onTimerEvent.bind(this), - this.decay * this.frequency * 1000); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -function $() { - var results = [], element; - for (var i = 0; i < arguments.length; i++) { - element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - results.push(Element.extend(element)); - } - return results.length < 2 ? results[0] : results; -} - -document.getElementsByClassName = function(className, parentElement) { - var children = ($(parentElement) || document.body).getElementsByTagName('*'); - return $A(children).inject([], function(elements, child) { - if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(Element.extend(child)); - return elements; - }); -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Element) - var Element = new Object(); - -Element.extend = function(element) { - if (!element) return; - if (_nativeExtensions) return element; - - if (!element._extended && element.tagName && element != window) { - var methods = Element.Methods, cache = Element.extend.cache; - for (property in methods) { - var value = methods[property]; - if (typeof value == 'function') - element[property] = cache.findOrStore(value); - } - } - - element._extended = true; - return element; -} - -Element.extend.cache = { - findOrStore: function(value) { - return this[value] = this[value] || function() { - return value.apply(null, [this].concat($A(arguments))); - } - } -} - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - Element[Element.visible(element) ? 'hide' : 'show'](element); - } - }, - - hide: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = 'none'; - } - }, - - show: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = ''; - } - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - }, - - update: function(element, html) { - $(element).innerHTML = html.stripScripts(); - setTimeout(function() {html.evalScripts()}, 10); - }, - - replace: function(element, html) { - element = $(element); - if (element.outerHTML) { - element.outerHTML = html.stripScripts(); - } else { - var range = element.ownerDocument.createRange(); - range.selectNodeContents(element); - element.parentNode.replaceChild( - range.createContextualFragment(html.stripScripts()), element); - } - setTimeout(function() {html.evalScripts()}, 10); - }, - - getHeight: function(element) { - element = $(element); - return element.offsetHeight; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).include(className); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).add(className); - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).remove(className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - Element.remove(node); - } - }, - - empty: function(element) { - return $(element).innerHTML.match(/^\s*$/); - }, - - childOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - while (element = element.parentNode) - if (element == ancestor) return true; - return false; - }, - - scrollTo: function(element) { - element = $(element); - var x = element.x ? element.x : element.offsetLeft, - y = element.y ? element.y : element.offsetTop; - window.scrollTo(x, y); - }, - - getStyle: function(element, style) { - element = $(element); - var value = element.style[style.camelize()]; - if (!value) { - if (document.defaultView && document.defaultView.getComputedStyle) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css.getPropertyValue(style) : null; - } else if (element.currentStyle) { - value = element.currentStyle[style.camelize()]; - } - } - - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) - if (Element.getStyle(element, 'position') == 'static') value = 'auto'; - - return value == 'auto' ? null : value; - }, - - setStyle: function(element, style) { - element = $(element); - for (var name in style) - element.style[name.camelize()] = style[name]; - }, - - getDimensions: function(element) { - element = $(element); - if (Element.getStyle(element, 'display') != 'none') - return {width: element.offsetWidth, height: element.offsetHeight}; - - // All *Width and *Height properties give 0 on elements with display none, - // so enable the element temporarily - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = ''; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = 'none'; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined - if (window.opera) { - element.style.top = 0; - element.style.left = 0; - } - } - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return; - element._overflow = element.style.overflow; - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') - element.style.overflow = 'hidden'; - }, - - undoClipping: function(element) { - element = $(element); - if (element._overflow) return; - element.style.overflow = element._overflow; - element._overflow = undefined; - } -} - -Object.extend(Element, Element.Methods); - -var _nativeExtensions = false; - -if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - var HTMLElement = {} - HTMLElement.prototype = document.createElement('div').__proto__; -} - -Element.addMethods = function(methods) { - Object.extend(Element.Methods, methods || {}); - - if(typeof HTMLElement != 'undefined') { - var methods = Element.Methods, cache = Element.extend.cache; - for (property in methods) { - var value = methods[property]; - if (typeof value == 'function') - HTMLElement.prototype[property] = cache.findOrStore(value); - } - _nativeExtensions = true; - } -} - -Element.addMethods(); - -var Toggle = new Object(); -Toggle.display = Element.toggle; - -/*--------------------------------------------------------------------------*/ - -Abstract.Insertion = function(adjacency) { - this.adjacency = adjacency; -} - -Abstract.Insertion.prototype = { - initialize: function(element, content) { - this.element = $(element); - this.content = content.stripScripts(); - - if (this.adjacency && this.element.insertAdjacentHTML) { - try { - this.element.insertAdjacentHTML(this.adjacency, this.content); - } catch (e) { - var tagName = this.element.tagName.toLowerCase(); - if (tagName == 'tbody' || tagName == 'tr') { - this.insertContent(this.contentFromAnonymousTable()); - } else { - throw e; - } - } - } else { - this.range = this.element.ownerDocument.createRange(); - if (this.initializeRange) this.initializeRange(); - this.insertContent([this.range.createContextualFragment(this.content)]); - } - - setTimeout(function() {content.evalScripts()}, 10); - }, - - contentFromAnonymousTable: function() { - var div = document.createElement('div'); - div.innerHTML = '' + this.content + '
    '; - return $A(div.childNodes[0].childNodes[0].childNodes); - } -} - -var Insertion = new Object(); - -Insertion.Before = Class.create(); -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { - initializeRange: function() { - this.range.setStartBefore(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, this.element); - }).bind(this)); - } -}); - -Insertion.Top = Class.create(); -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(true); - }, - - insertContent: function(fragments) { - fragments.reverse(false).each((function(fragment) { - this.element.insertBefore(fragment, this.element.firstChild); - }).bind(this)); - } -}); - -Insertion.Bottom = Class.create(); -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.appendChild(fragment); - }).bind(this)); - } -}); - -Insertion.After = Class.create(); -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { - initializeRange: function() { - this.range.setStartAfter(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, - this.element.nextSibling); - }).bind(this)); - } -}); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set(this.toArray().concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set(this.select(function(className) { - return className != classNameToRemove; - }).join(' ')); - }, - - toString: function() { - return this.toArray().join(' '); - } -} - -Object.extend(Element.ClassNames.prototype, Enumerable); -var Selector = Class.create(); -Selector.prototype = { - initialize: function(expression) { - this.params = {classNames: []}; - this.expression = expression.toString().strip(); - this.parseExpression(); - this.compileMatcher(); - }, - - parseExpression: function() { - function abort(message) { throw 'Parse error in selector: ' + message; } - - if (this.expression == '') abort('empty expression'); - - var params = this.params, expr = this.expression, match, modifier, clause, rest; - while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { - params.attributes = params.attributes || []; - params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); - expr = match[1]; - } - - if (expr == '*') return this.params.wildcard = true; - - while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { - modifier = match[1], clause = match[2], rest = match[3]; - switch (modifier) { - case '#': params.id = clause; break; - case '.': params.classNames.push(clause); break; - case '': - case undefined: params.tagName = clause.toUpperCase(); break; - default: abort(expr.inspect()); - } - expr = rest; - } - - if (expr.length > 0) abort(expr.inspect()); - }, - - buildMatchExpression: function() { - var params = this.params, conditions = [], clause; - - if (params.wildcard) - conditions.push('true'); - if (clause = params.id) - conditions.push('element.id == ' + clause.inspect()); - if (clause = params.tagName) - conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); - if ((clause = params.classNames).length > 0) - for (var i = 0; i < clause.length; i++) - conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); - if (clause = params.attributes) { - clause.each(function(attribute) { - var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; - var splitValueBy = function(delimiter) { - return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; - } - - switch (attribute.operator) { - case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; - case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; - case '|=': conditions.push( - splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() - ); break; - case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; - case '': - case undefined: conditions.push(value + ' != null'); break; - default: throw 'Unknown operator ' + attribute.operator + ' in selector'; - } - }); - } - - return conditions.join(' && '); - }, - - compileMatcher: function() { - this.match = new Function('element', 'if (!element.tagName) return false; \n' + - 'return ' + this.buildMatchExpression()); - }, - - findElements: function(scope) { - var element; - - if (element = $(this.params.id)) - if (this.match(element)) - if (!scope || Element.childOf(element, scope)) - return [element]; - - scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); - - var results = []; - for (var i = 0; i < scope.length; i++) - if (this.match(element = scope[i])) - results.push(Element.extend(element)); - - return results; - }, - - toString: function() { - return this.expression; - } -} - -function $$() { - return $A(arguments).map(function(expression) { - return expression.strip().split(/\s+/).inject([null], function(results, expr) { - var selector = new Selector(expr); - return results.map(selector.findElements.bind(selector)).flatten(); - }); - }).flatten(); -} -var Field = { - clear: function() { - for (var i = 0; i < arguments.length; i++) - $(arguments[i]).value = ''; - }, - - focus: function(element) { - $(element).focus(); - }, - - present: function() { - for (var i = 0; i < arguments.length; i++) - if ($(arguments[i]).value == '') return false; - return true; - }, - - select: function(element) { - $(element).select(); - }, - - activate: function(element) { - element = $(element); - element.focus(); - if (element.select) - element.select(); - } -} - -/*--------------------------------------------------------------------------*/ - -var Form = { - serialize: function(form) { - var elements = Form.getElements($(form)); - var queryComponents = new Array(); - - for (var i = 0; i < elements.length; i++) { - var queryComponent = Form.Element.serialize(elements[i]); - if (queryComponent) - queryComponents.push(queryComponent); - } - - return queryComponents.join('&'); - }, - - getElements: function(form) { - form = $(form); - var elements = new Array(); - - for (var tagName in Form.Element.Serializers) { - var tagElements = form.getElementsByTagName(tagName); - for (var j = 0; j < tagElements.length; j++) - elements.push(tagElements[j]); - } - return elements; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) - return inputs; - - var matchingInputs = new Array(); - for (var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || - (name && input.name != name)) - continue; - matchingInputs.push(input); - } - - return matchingInputs; - }, - - disable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.blur(); - element.disabled = 'true'; - } - }, - - enable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.disabled = ''; - } - }, - - findFirstElement: function(form) { - return Form.getElements(form).find(function(element) { - return element.type != 'hidden' && !element.disabled && - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - Field.activate(Form.findFirstElement(form)); - }, - - reset: function(form) { - $(form).reset(); - } -} - -Form.Element = { - serialize: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) { - var key = encodeURIComponent(parameter[0]); - if (key.length == 0) return; - - if (parameter[1].constructor != Array) - parameter[1] = [parameter[1]]; - - return parameter[1].map(function(value) { - return key + '=' + encodeURIComponent(value); - }).join('&'); - } - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) - return parameter[1]; - } -} - -Form.Element.Serializers = { - input: function(element) { - switch (element.type.toLowerCase()) { - case 'submit': - case 'hidden': - case 'password': - case 'text': - return Form.Element.Serializers.textarea(element); - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element); - } - return false; - }, - - inputSelector: function(element) { - if (element.checked) - return [element.name, element.value]; - }, - - textarea: function(element) { - return [element.name, element.value]; - }, - - select: function(element) { - return Form.Element.Serializers[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - }, - - selectOne: function(element) { - var value = '', opt, index = element.selectedIndex; - if (index >= 0) { - opt = element.options[index]; - value = opt.value || opt.text; - } - return [element.name, value]; - }, - - selectMany: function(element) { - var value = []; - for (var i = 0; i < element.length; i++) { - var opt = element.options[i]; - if (opt.selected) - value.push(opt.value || opt.text); - } - return [element.name, value]; - } -} - -/*--------------------------------------------------------------------------*/ - -var $F = Form.Element.getValue; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = function() {} -Abstract.TimedObserver.prototype = { - initialize: function(element, frequency, callback) { - this.frequency = frequency; - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - } -} - -Form.Element.Observer = Class.create(); -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(); -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = function() {} -Abstract.EventObserver.prototype = { - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - var elements = Form.getElements(this.element); - for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - case 'password': - case 'text': - case 'textarea': - case 'select-one': - case 'select-multiple': - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -} - -Form.Element.EventObserver = Class.create(); -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(); -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) { - var Event = new Object(); -} - -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - - element: function(event) { - return event.target || event.srcElement; - }, - - isLeftClick: function(event) { - return (((event.which) && (event.which == 1)) || - ((event.button) && (event.button == 1))); - }, - - pointerX: function(event) { - return event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)); - }, - - pointerY: function(event) { - return event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)); - }, - - stop: function(event) { - if (event.preventDefault) { - event.preventDefault(); - event.stopPropagation(); - } else { - event.returnValue = false; - event.cancelBubble = true; - } - }, - - // find the first node with the given tagName, starting from the - // node the event was triggered on; traverses the DOM upwards - findElement: function(event, tagName) { - var element = Event.element(event); - while (element.parentNode && (!element.tagName || - (element.tagName.toUpperCase() != tagName.toUpperCase()))) - element = element.parentNode; - return element; - }, - - observers: false, - - _observeAndCache: function(element, name, observer, useCapture) { - if (!this.observers) this.observers = []; - if (element.addEventListener) { - this.observers.push([element, name, observer, useCapture]); - element.addEventListener(name, observer, useCapture); - } else if (element.attachEvent) { - this.observers.push([element, name, observer, useCapture]); - element.attachEvent('on' + name, observer); - } - }, - - unloadCache: function() { - if (!Event.observers) return; - for (var i = 0; i < Event.observers.length; i++) { - Event.stopObserving.apply(this, Event.observers[i]); - Event.observers[i][0] = null; - } - Event.observers = false; - }, - - observe: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.attachEvent)) - name = 'keydown'; - - this._observeAndCache(element, name, observer, useCapture); - }, - - stopObserving: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.detachEvent)) - name = 'keydown'; - - if (element.removeEventListener) { - element.removeEventListener(name, observer, useCapture); - } else if (element.detachEvent) { - element.detachEvent('on' + name, observer); - } - } -}); - -/* prevent memory leaks in IE */ -if (navigator.appVersion.match(/\bMSIE\b/)) - Event.observe(window, 'unload', Event.unloadCache, false); -var Position = { - // set to true if needed, warning: firefox performance problems - // NOT neeeded for page scrolling, only if draggable contained in - // scrollable elements - includeScrollOffsets: false, - - // must be called before calling withinIncludingScrolloffset, every time the - // page is scrolled - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - realOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return [valueL, valueT]; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [valueL, valueT]; - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return [valueL, valueT]; - }, - - offsetParent: function(element) { - if (element.offsetParent) return element.offsetParent; - if (element == document.body) return element; - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return element; - - return document.body; - }, - - // caches x/y coordinate pair to use with overlap - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = this.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = this.realOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = this.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - // within must be called directly before - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - clone: function(source, target) { - source = $(source); - target = $(target); - target.style.position = 'absolute'; - var offsets = this.cumulativeOffset(source); - target.style.top = offsets[1] + 'px'; - target.style.left = offsets[0] + 'px'; - target.style.width = source.offsetWidth + 'px'; - target.style.height = source.offsetHeight + 'px'; - }, - - page: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - // Safari fix - if (element.offsetParent==document.body) - if (Element.getStyle(element,'position')=='absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } while (element = element.parentNode); - - return [valueL, valueT]; - }, - - clone: function(source, target) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || {}) - - // find page position of source - source = $(source); - var p = Position.page(source); - - // find coordinate system to use - target = $(target); - var delta = [0, 0]; - var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas - if (Element.getStyle(target,'position') == 'absolute') { - parent = Position.offsetParent(target); - delta = Position.page(parent); - } - - // correct by body offsets (fixes Safari) - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - // set position - if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if(options.setWidth) target.style.width = source.offsetWidth + 'px'; - if(options.setHeight) target.style.height = source.offsetHeight + 'px'; - }, - - absolutize: function(element) { - element = $(element); - if (element.style.position == 'absolute') return; - Position.prepare(); - - var offsets = Position.positionedOffset(element); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px';; - element.style.left = left + 'px';; - element.style.width = width + 'px';; - element.style.height = height + 'px';; - }, - - relativize: function(element) { - element = $(element); - if (element.style.position == 'relative') return; - Position.prepare(); - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - } -} - -// Safari returns margins on body which is incorrect if the child is absolutely -// positioned. For performance reasons, redefine Position.cumulativeOffset for -// KHTML/WebKit only. -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - Position.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return [valueL, valueT]; - } -} \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/builder.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/builder.js deleted file mode 100644 index 5b15ba93..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/builder.js +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// See scriptaculous.js for full license. - -var Builder = { - NODEMAP: { - AREA: 'map', - CAPTION: 'table', - COL: 'table', - COLGROUP: 'table', - LEGEND: 'fieldset', - OPTGROUP: 'select', - OPTION: 'select', - PARAM: 'object', - TBODY: 'table', - TD: 'table', - TFOOT: 'table', - TH: 'table', - THEAD: 'table', - TR: 'table' - }, - // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, - // due to a Firefox bug - node: function(elementName) { - elementName = elementName.toUpperCase(); - - // try innerHTML approach - var parentTag = this.NODEMAP[elementName] || 'div'; - var parentElement = document.createElement(parentTag); - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" + elementName + ">"; - } catch(e) {} - var element = parentElement.firstChild || null; - - // see if browser added wrapping tags - if(element && (element.tagName != elementName)) - element = element.getElementsByTagName(elementName)[0]; - - // fallback to createElement approach - if(!element) element = document.createElement(elementName); - - // abort if nothing could be created - if(!element) return; - - // attributes (or text) - if(arguments[1]) - if(this._isStringOrNumber(arguments[1]) || - (arguments[1] instanceof Array)) { - this._children(element, arguments[1]); - } else { - var attrs = this._attributes(arguments[1]); - if(attrs.length) { - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" +elementName + " " + - attrs + ">"; - } catch(e) {} - element = parentElement.firstChild || null; - // workaround firefox 1.0.X bug - if(!element) { - element = document.createElement(elementName); - for(attr in arguments[1]) - element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; - } - if(element.tagName != elementName) - element = parentElement.getElementsByTagName(elementName)[0]; - } - } - - // text, or array of children - if(arguments[2]) - this._children(element, arguments[2]); - - return element; - }, - _text: function(text) { - return document.createTextNode(text); - }, - _attributes: function(attributes) { - var attrs = []; - for(attribute in attributes) - attrs.push((attribute=='className' ? 'class' : attribute) + - '="' + attributes[attribute].toString().escapeHTML() + '"'); - return attrs.join(" "); - }, - _children: function(element, children) { - if(typeof children=='object') { // array can hold nodes and text - children.flatten().each( function(e) { - if(typeof e=='object') - element.appendChild(e) - else - if(Builder._isStringOrNumber(e)) - element.appendChild(Builder._text(e)); - }); - } else - if(Builder._isStringOrNumber(children)) - element.appendChild(Builder._text(children)); - }, - _isStringOrNumber: function(param) { - return(typeof param=='string' || typeof param=='number'); - } -} \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/controls.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/controls.js deleted file mode 100644 index de0261ed..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/controls.js +++ /dev/null @@ -1,815 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005 Jon Tirsen (http://www.tirsen.com) -// Contributors: -// Richard Livsey -// Rahul Bhargava -// Rob Wills -// -// See scriptaculous.js for full license. - -// Autocompleter.Base handles all the autocompletion functionality -// that's independent of the data source for autocompletion. This -// includes drawing the autocompletion menu, observing keyboard -// and mouse events, and similar. -// -// Specific autocompleters need to provide, at the very least, -// a getUpdatedChoices function that will be invoked every time -// the text inside the monitored textbox changes. This method -// should get the text for which to provide autocompletion by -// invoking this.getToken(), NOT by directly accessing -// this.element.value. This is to allow incremental tokenized -// autocompletion. Specific auto-completion logic (AJAX, etc) -// belongs in getUpdatedChoices. -// -// Tokenized incremental autocompletion is enabled automatically -// when an autocompleter is instantiated with the 'tokens' option -// in the options parameter, e.g.: -// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); -// will incrementally autocomplete with a comma as the token. -// Additionally, ',' in the above example can be replaced with -// a token array, e.g. { tokens: [',', '\n'] } which -// enables autocompletion on multiple tokens. This is most -// useful when one of the tokens is \n (a newline), as it -// allows smart autocompletion after linebreaks. - -var Autocompleter = {} -Autocompleter.Base = function() {}; -Autocompleter.Base.prototype = { - baseInitialize: function(element, update, options) { - this.element = $(element); - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; - this.entryCount = 0; - - if (this.setOptions) - this.setOptions(options); - else - this.options = options || {}; - - this.options.paramName = this.options.paramName || this.element.name; - this.options.tokens = this.options.tokens || []; - this.options.frequency = this.options.frequency || 0.4; - this.options.minChars = this.options.minChars || 1; - this.options.onShow = this.options.onShow || - function(element, update){ - if(!update.style.position || update.style.position=='absolute') { - update.style.position = 'absolute'; - Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight}); - } - Effect.Appear(update,{duration:0.15}); - }; - this.options.onHide = this.options.onHide || - function(element, update){ new Effect.Fade(update,{duration:0.15}) }; - - if (typeof(this.options.tokens) == 'string') - this.options.tokens = new Array(this.options.tokens); - - this.observer = null; - - this.element.setAttribute('autocomplete','off'); - - Element.hide(this.update); - - Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); - Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); - }, - - show: function() { - if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); - if(!this.iefix && - (navigator.appVersion.indexOf('MSIE')>0) && - (navigator.userAgent.indexOf('Opera')<0) && - (Element.getStyle(this.update, 'position')=='absolute')) { - new Insertion.After(this.update, - ''); - this.iefix = $(this.update.id+'_iefix'); - } - if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); - }, - - fixIEOverlapping: function() { - Position.clone(this.update, this.iefix); - this.iefix.style.zIndex = 1; - this.update.style.zIndex = 2; - Element.show(this.iefix); - }, - - hide: function() { - this.stopIndicator(); - if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); - if(this.iefix) Element.hide(this.iefix); - }, - - startIndicator: function() { - if(this.options.indicator) Element.show(this.options.indicator); - }, - - stopIndicator: function() { - if(this.options.indicator) Element.hide(this.options.indicator); - }, - - onKeyPress: function(event) { - if(this.active) - switch(event.keyCode) { - case Event.KEY_TAB: - case Event.KEY_RETURN: - this.selectEntry(); - Event.stop(event); - case Event.KEY_ESC: - this.hide(); - this.active = false; - Event.stop(event); - return; - case Event.KEY_LEFT: - case Event.KEY_RIGHT: - return; - case Event.KEY_UP: - this.markPrevious(); - this.render(); - if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || - (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return; - - this.changed = true; - this.hasFocus = true; - - if(this.observer) clearTimeout(this.observer); - this.observer = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - activate: function() { - this.changed = false; - this.hasFocus = true; - this.getUpdatedChoices(); - }, - - onHover: function(event) { - var element = Event.findElement(event, 'LI'); - if(this.index != element.autocompleteIndex) - { - this.index = element.autocompleteIndex; - this.render(); - } - Event.stop(event); - }, - - onClick: function(event) { - var element = Event.findElement(event, 'LI'); - this.index = element.autocompleteIndex; - this.selectEntry(); - this.hide(); - }, - - onBlur: function(event) { - // needed to make click events working - setTimeout(this.hide.bind(this), 250); - this.hasFocus = false; - this.active = false; - }, - - render: function() { - if(this.entryCount > 0) { - for (var i = 0; i < this.entryCount; i++) - this.index==i ? - Element.addClassName(this.getEntry(i),"selected") : - Element.removeClassName(this.getEntry(i),"selected"); - - if(this.hasFocus) { - this.show(); - this.active = true; - } - } else { - this.active = false; - this.hide(); - } - }, - - markPrevious: function() { - if(this.index > 0) this.index-- - else this.index = this.entryCount-1; - }, - - markNext: function() { - if(this.index < this.entryCount-1) this.index++ - else this.index = 0; - }, - - getEntry: function(index) { - return this.update.firstChild.childNodes[index]; - }, - - getCurrentEntry: function() { - return this.getEntry(this.index); - }, - - selectEntry: function() { - this.active = false; - this.updateElement(this.getCurrentEntry()); - }, - - updateElement: function(selectedElement) { - if (this.options.updateElement) { - this.options.updateElement(selectedElement); - return; - } - var value = ''; - if (this.options.select) { - var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; - if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); - } else - value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - - var lastTokenPos = this.findLastToken(); - if (lastTokenPos != -1) { - var newValue = this.element.value.substr(0, lastTokenPos + 1); - var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); - if (whitespace) - newValue += whitespace[0]; - this.element.value = newValue + value; - } else { - this.element.value = value; - } - this.element.focus(); - - if (this.options.afterUpdateElement) - this.options.afterUpdateElement(this.element, selectedElement); - }, - - updateChoices: function(choices) { - if(!this.changed && this.hasFocus) { - this.update.innerHTML = choices; - Element.cleanWhitespace(this.update); - Element.cleanWhitespace(this.update.firstChild); - - if(this.update.firstChild && this.update.firstChild.childNodes) { - this.entryCount = - this.update.firstChild.childNodes.length; - for (var i = 0; i < this.entryCount; i++) { - var entry = this.getEntry(i); - entry.autocompleteIndex = i; - this.addObservers(entry); - } - } else { - this.entryCount = 0; - } - - this.stopIndicator(); - - this.index = 0; - this.render(); - } - }, - - addObservers: function(element) { - Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); - Event.observe(element, "click", this.onClick.bindAsEventListener(this)); - }, - - onObserverEvent: function() { - this.changed = false; - if(this.getToken().length>=this.options.minChars) { - this.startIndicator(); - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - }, - - getToken: function() { - var tokenPos = this.findLastToken(); - if (tokenPos != -1) - var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); - else - var ret = this.element.value; - - return /\n/.test(ret) ? '' : ret; - }, - - findLastToken: function() { - var lastTokenPos = -1; - - for (var i=0; i lastTokenPos) - lastTokenPos = thisTokenPos; - } - return lastTokenPos; - } -} - -Ajax.Autocompleter = Class.create(); -Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { - initialize: function(element, update, url, options) { - this.baseInitialize(element, update, options); - this.options.asynchronous = true; - this.options.onComplete = this.onComplete.bind(this); - this.options.defaultParams = this.options.parameters || null; - this.url = url; - }, - - getUpdatedChoices: function() { - entry = encodeURIComponent(this.options.paramName) + '=' + - encodeURIComponent(this.getToken()); - - this.options.parameters = this.options.callback ? - this.options.callback(this.element, entry) : entry; - - if(this.options.defaultParams) - this.options.parameters += '&' + this.options.defaultParams; - - new Ajax.Request(this.url, this.options); - }, - - onComplete: function(request) { - this.updateChoices(request.responseText); - } - -}); - -// The local array autocompleter. Used when you'd prefer to -// inject an array of autocompletion options into the page, rather -// than sending out Ajax queries, which can be quite slow sometimes. -// -// The constructor takes four parameters. The first two are, as usual, -// the id of the monitored textbox, and id of the autocompletion menu. -// The third is the array you want to autocomplete from, and the fourth -// is the options block. -// -// Extra local autocompletion options: -// - choices - How many autocompletion choices to offer -// -// - partialSearch - If false, the autocompleter will match entered -// text only at the beginning of strings in the -// autocomplete array. Defaults to true, which will -// match text at the beginning of any *word* in the -// strings in the autocomplete array. If you want to -// search anywhere in the string, additionally set -// the option fullSearch to true (default: off). -// -// - fullSsearch - Search anywhere in autocomplete array strings. -// -// - partialChars - How many characters to enter before triggering -// a partial match (unlike minChars, which defines -// how many characters are required to do any match -// at all). Defaults to 2. -// -// - ignoreCase - Whether to ignore case when autocompleting. -// Defaults to true. -// -// It's possible to pass in a custom function as the 'selector' -// option, if you prefer to write your own autocompletion logic. -// In that case, the other options above will not apply unless -// you support them. - -Autocompleter.Local = Class.create(); -Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { - initialize: function(element, update, array, options) { - this.baseInitialize(element, update, options); - this.options.array = array; - }, - - getUpdatedChoices: function() { - this.updateChoices(this.options.selector(this)); - }, - - setOptions: function(options) { - this.options = Object.extend({ - choices: 10, - partialSearch: true, - partialChars: 2, - ignoreCase: true, - fullSearch: false, - selector: function(instance) { - var ret = []; // Beginning matches - var partial = []; // Inside matches - var entry = instance.getToken(); - var count = 0; - - for (var i = 0; i < instance.options.array.length && - ret.length < instance.options.choices ; i++) { - - var elem = instance.options.array[i]; - var foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase()) : - elem.indexOf(entry); - - while (foundPos != -1) { - if (foundPos == 0 && elem.length != entry.length) { - ret.push("
  • " + elem.substr(0, entry.length) + "" + - elem.substr(entry.length) + "
  • "); - break; - } else if (entry.length >= instance.options.partialChars && - instance.options.partialSearch && foundPos != -1) { - if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { - partial.push("
  • " + elem.substr(0, foundPos) + "" + - elem.substr(foundPos, entry.length) + "" + elem.substr( - foundPos + entry.length) + "
  • "); - break; - } - } - - foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : - elem.indexOf(entry, foundPos + 1); - - } - } - if (partial.length) - ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) - return "
      " + ret.join('') + "
    "; - } - }, options || {}); - } -}); - -// AJAX in-place editor -// -// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor - -// Use this if you notice weird scrolling problems on some browsers, -// the DOM might be a bit confused when this gets called so do this -// waits 1 ms (with setTimeout) until it does the activation -Field.scrollFreeActivate = function(field) { - setTimeout(function() { - Field.activate(field); - }, 1); -} - -Ajax.InPlaceEditor = Class.create(); -Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; -Ajax.InPlaceEditor.prototype = { - initialize: function(element, url, options) { - this.url = url; - this.element = $(element); - - this.options = Object.extend({ - okButton: true, - okText: "ok", - cancelLink: true, - cancelText: "cancel", - savingText: "Saving...", - clickToEditText: "Click to edit", - okText: "ok", - rows: 1, - onComplete: function(transport, element) { - new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); - }, - onFailure: function(transport) { - alert("Error communicating with the server: " + transport.responseText.stripTags()); - }, - callback: function(form) { - return Form.serialize(form); - }, - handleLineBreaks: true, - loadingText: 'Loading...', - savingClassName: 'inplaceeditor-saving', - loadingClassName: 'inplaceeditor-loading', - formClassName: 'inplaceeditor-form', - highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, - highlightendcolor: "#FFFFFF", - externalControl: null, - submitOnBlur: false, - ajaxOptions: {}, - evalScripts: false - }, options || {}); - - if(!this.options.formId && this.element.id) { - this.options.formId = this.element.id + "-inplaceeditor"; - if ($(this.options.formId)) { - // there's already a form with that name, don't specify an id - this.options.formId = null; - } - } - - if (this.options.externalControl) { - this.options.externalControl = $(this.options.externalControl); - } - - this.originalBackground = Element.getStyle(this.element, 'background-color'); - if (!this.originalBackground) { - this.originalBackground = "transparent"; - } - - this.element.title = this.options.clickToEditText; - - this.onclickListener = this.enterEditMode.bindAsEventListener(this); - this.mouseoverListener = this.enterHover.bindAsEventListener(this); - this.mouseoutListener = this.leaveHover.bindAsEventListener(this); - Event.observe(this.element, 'click', this.onclickListener); - Event.observe(this.element, 'mouseover', this.mouseoverListener); - Event.observe(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.observe(this.options.externalControl, 'click', this.onclickListener); - Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - }, - enterEditMode: function(evt) { - if (this.saving) return; - if (this.editing) return; - this.editing = true; - this.onEnterEditMode(); - if (this.options.externalControl) { - Element.hide(this.options.externalControl); - } - Element.hide(this.element); - this.createForm(); - this.element.parentNode.insertBefore(this.form, this.element); - Field.scrollFreeActivate(this.editField); - // stop the event to avoid a page refresh in Safari - if (evt) { - Event.stop(evt); - } - return false; - }, - createForm: function() { - this.form = document.createElement("form"); - this.form.id = this.options.formId; - Element.addClassName(this.form, this.options.formClassName) - this.form.onsubmit = this.onSubmit.bind(this); - - this.createEditField(); - - if (this.options.textarea) { - var br = document.createElement("br"); - this.form.appendChild(br); - } - - if (this.options.okButton) { - okButton = document.createElement("input"); - okButton.type = "submit"; - okButton.value = this.options.okText; - okButton.className = 'editor_ok_button'; - this.form.appendChild(okButton); - } - - if (this.options.cancelLink) { - cancelLink = document.createElement("a"); - cancelLink.href = "#"; - cancelLink.appendChild(document.createTextNode(this.options.cancelText)); - cancelLink.onclick = this.onclickCancel.bind(this); - cancelLink.className = 'editor_cancel'; - this.form.appendChild(cancelLink); - } - }, - hasHTMLLineBreaks: function(string) { - if (!this.options.handleLineBreaks) return false; - return string.match(/
    /i); - }, - convertHTMLLineBreaks: function(string) { - return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); - }, - createEditField: function() { - var text; - if(this.options.loadTextURL) { - text = this.options.loadingText; - } else { - text = this.getText(); - } - - var obj = this; - - if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { - this.options.textarea = false; - var textField = document.createElement("input"); - textField.obj = this; - textField.type = "text"; - textField.name = "value"; - textField.value = text; - textField.style.backgroundColor = this.options.highlightcolor; - textField.className = 'editor_field'; - var size = this.options.size || this.options.cols || 0; - if (size != 0) textField.size = size; - if (this.options.submitOnBlur) - textField.onblur = this.onSubmit.bind(this); - this.editField = textField; - } else { - this.options.textarea = true; - var textArea = document.createElement("textarea"); - textArea.obj = this; - textArea.name = "value"; - textArea.value = this.convertHTMLLineBreaks(text); - textArea.rows = this.options.rows; - textArea.cols = this.options.cols || 40; - textArea.className = 'editor_field'; - if (this.options.submitOnBlur) - textArea.onblur = this.onSubmit.bind(this); - this.editField = textArea; - } - - if(this.options.loadTextURL) { - this.loadExternalText(); - } - this.form.appendChild(this.editField); - }, - getText: function() { - return this.element.innerHTML; - }, - loadExternalText: function() { - Element.addClassName(this.form, this.options.loadingClassName); - this.editField.disabled = true; - new Ajax.Request( - this.options.loadTextURL, - Object.extend({ - asynchronous: true, - onComplete: this.onLoadedExternalText.bind(this) - }, this.options.ajaxOptions) - ); - }, - onLoadedExternalText: function(transport) { - Element.removeClassName(this.form, this.options.loadingClassName); - this.editField.disabled = false; - this.editField.value = transport.responseText.stripTags(); - }, - onclickCancel: function() { - this.onComplete(); - this.leaveEditMode(); - return false; - }, - onFailure: function(transport) { - this.options.onFailure(transport); - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - this.oldInnerHTML = null; - } - return false; - }, - onSubmit: function() { - // onLoading resets these so we need to save them away for the Ajax call - var form = this.form; - var value = this.editField.value; - - // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... - // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... - // to be displayed indefinitely - this.onLoading(); - - if (this.options.evalScripts) { - new Ajax.Request( - this.url, Object.extend({ - parameters: this.options.callback(form, value), - onComplete: this.onComplete.bind(this), - onFailure: this.onFailure.bind(this), - asynchronous:true, - evalScripts:true - }, this.options.ajaxOptions)); - } else { - new Ajax.Updater( - { success: this.element, - // don't update on failure (this could be an option) - failure: null }, - this.url, Object.extend({ - parameters: this.options.callback(form, value), - onComplete: this.onComplete.bind(this), - onFailure: this.onFailure.bind(this) - }, this.options.ajaxOptions)); - } - // stop the event to avoid a page refresh in Safari - if (arguments.length > 1) { - Event.stop(arguments[0]); - } - return false; - }, - onLoading: function() { - this.saving = true; - this.removeForm(); - this.leaveHover(); - this.showSaving(); - }, - showSaving: function() { - this.oldInnerHTML = this.element.innerHTML; - this.element.innerHTML = this.options.savingText; - Element.addClassName(this.element, this.options.savingClassName); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - }, - removeForm: function() { - if(this.form) { - if (this.form.parentNode) Element.remove(this.form); - this.form = null; - } - }, - enterHover: function() { - if (this.saving) return; - this.element.style.backgroundColor = this.options.highlightcolor; - if (this.effect) { - this.effect.cancel(); - } - Element.addClassName(this.element, this.options.hoverClassName) - }, - leaveHover: function() { - if (this.options.backgroundColor) { - this.element.style.backgroundColor = this.oldBackground; - } - Element.removeClassName(this.element, this.options.hoverClassName) - if (this.saving) return; - this.effect = new Effect.Highlight(this.element, { - startcolor: this.options.highlightcolor, - endcolor: this.options.highlightendcolor, - restorecolor: this.originalBackground - }); - }, - leaveEditMode: function() { - Element.removeClassName(this.element, this.options.savingClassName); - this.removeForm(); - this.leaveHover(); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - if (this.options.externalControl) { - Element.show(this.options.externalControl); - } - this.editing = false; - this.saving = false; - this.oldInnerHTML = null; - this.onLeaveEditMode(); - }, - onComplete: function(transport) { - this.leaveEditMode(); - this.options.onComplete.bind(this)(transport, this.element); - }, - onEnterEditMode: function() {}, - onLeaveEditMode: function() {}, - dispose: function() { - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - } - this.leaveEditMode(); - Event.stopObserving(this.element, 'click', this.onclickListener); - Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); - Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - } -}; - -Ajax.InPlaceCollectionEditor = Class.create(); -Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); -Object.extend(Ajax.InPlaceCollectionEditor.prototype, { - createEditField: function() { - if (!this.cached_selectTag) { - var selectTag = document.createElement("select"); - var collection = this.options.collection || []; - var optionTag; - collection.each(function(e,i) { - optionTag = document.createElement("option"); - optionTag.value = (e instanceof Array) ? e[0] : e; - if(this.options.value==optionTag.value) optionTag.selected = true; - optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); - selectTag.appendChild(optionTag); - }.bind(this)); - this.cached_selectTag = selectTag; - } - - this.editField = this.cached_selectTag; - if(this.options.loadTextURL) this.loadExternalText(); - this.form.appendChild(this.editField); - this.options.callback = function(form, value) { - return "value=" + encodeURIComponent(value); - } - } -}); - -// Delayed observer, like Form.Element.Observer, -// but waits for delay after last key input -// Ideal for live-search fields - -Form.Element.DelayedObserver = Class.create(); -Form.Element.DelayedObserver.prototype = { - initialize: function(element, delay, callback) { - this.delay = delay || 0.5; - this.element = $(element); - this.callback = callback; - this.timer = null; - this.lastValue = $F(this.element); - Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); - }, - delayedListener: function(event) { - if(this.lastValue == $F(this.element)) return; - if(this.timer) clearTimeout(this.timer); - this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); - this.lastValue = $F(this.element); - }, - onTimerEvent: function() { - this.timer = null; - this.callback(this.element, $F(this.element)); - } -}; diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/dragdrop.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/dragdrop.js deleted file mode 100644 index be2a30f5..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/dragdrop.js +++ /dev/null @@ -1,915 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) -// -// See scriptaculous.js for full license. - -/*--------------------------------------------------------------------------*/ - -var Droppables = { - drops: [], - - remove: function(element) { - this.drops = this.drops.reject(function(d) { return d.element==$(element) }); - }, - - add: function(element) { - element = $(element); - var options = Object.extend({ - greedy: true, - hoverclass: null, - tree: false - }, arguments[1] || {}); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - if((typeof containment == 'object') && - (containment.constructor == Array)) { - containment.each( function(c) { options._containers.push($(c)) }); - } else { - options._containers.push($(containment)); - } - } - - if(options.accept) options.accept = [options.accept].flatten(); - - Element.makePositioned(element); // fix IE - options.element = element; - - this.drops.push(options); - }, - - findDeepestChild: function(drops) { - deepest = drops[0]; - - for (i = 1; i < drops.length; ++i) - if (Element.isParent(drops[i].element, deepest.element)) - deepest = drops[i]; - - return deepest; - }, - - isContained: function(element, drop) { - var containmentNode; - if(drop.tree) { - containmentNode = element.treeNode; - } else { - containmentNode = element.parentNode; - } - return drop._containers.detect(function(c) { return containmentNode == c }); - }, - - isAffected: function(point, element, drop) { - return ( - (drop.element!=element) && - ((!drop._containers) || - this.isContained(element, drop)) && - ((!drop.accept) || - (Element.classNames(element).detect( - function(v) { return drop.accept.include(v) } ) )) && - Position.within(drop.element, point[0], point[1]) ); - }, - - deactivate: function(drop) { - if(drop.hoverclass) - Element.removeClassName(drop.element, drop.hoverclass); - this.last_active = null; - }, - - activate: function(drop) { - if(drop.hoverclass) - Element.addClassName(drop.element, drop.hoverclass); - this.last_active = drop; - }, - - show: function(point, element) { - if(!this.drops.length) return; - var affected = []; - - if(this.last_active) this.deactivate(this.last_active); - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) - affected.push(drop); - }); - - if(affected.length>0) { - drop = Droppables.findDeepestChild(affected); - Position.within(drop.element, point[0], point[1]); - if(drop.onHover) - drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - - Droppables.activate(drop); - } - }, - - fire: function(event, element) { - if(!this.last_active) return; - Position.prepare(); - - if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) - if (this.last_active.onDrop) - this.last_active.onDrop(element, this.last_active.element, event); - }, - - reset: function() { - if(this.last_active) - this.deactivate(this.last_active); - } -} - -var Draggables = { - drags: [], - observers: [], - - register: function(draggable) { - if(this.drags.length == 0) { - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.updateDrag.bindAsEventListener(this); - this.eventKeypress = this.keyPress.bindAsEventListener(this); - - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - Event.observe(document, "keypress", this.eventKeypress); - } - this.drags.push(draggable); - }, - - unregister: function(draggable) { - this.drags = this.drags.reject(function(d) { return d==draggable }); - if(this.drags.length == 0) { - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - Event.stopObserving(document, "keypress", this.eventKeypress); - } - }, - - activate: function(draggable) { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; - }, - - deactivate: function() { - this.activeDraggable = null; - }, - - updateDrag: function(event) { - if(!this.activeDraggable) return; - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - // Mozilla-based browsers fire successive mousemove events with - // the same coordinates, prevent needless redrawing (moz bug?) - if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; - this._lastPointer = pointer; - this.activeDraggable.updateDrag(event, pointer); - }, - - endDrag: function(event) { - if(!this.activeDraggable) return; - this._lastPointer = null; - this.activeDraggable.endDrag(event); - this.activeDraggable = null; - }, - - keyPress: function(event) { - if(this.activeDraggable) - this.activeDraggable.keyPress(event); - }, - - addObserver: function(observer) { - this.observers.push(observer); - this._cacheObserverCallbacks(); - }, - - removeObserver: function(element) { // element instead of observer fixes mem leaks - this.observers = this.observers.reject( function(o) { return o.element==element }); - this._cacheObserverCallbacks(); - }, - - notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' - if(this[eventName+'Count'] > 0) - this.observers.each( function(o) { - if(o[eventName]) o[eventName](eventName, draggable, event); - }); - }, - - _cacheObserverCallbacks: function() { - ['onStart','onEnd','onDrag'].each( function(eventName) { - Draggables[eventName+'Count'] = Draggables.observers.select( - function(o) { return o[eventName]; } - ).length; - }); - } -} - -/*--------------------------------------------------------------------------*/ - -var Draggable = Class.create(); -Draggable.prototype = { - initialize: function(element) { - var options = Object.extend({ - handle: false, - starteffect: function(element) { - element._opacity = Element.getOpacity(element); - new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); - }, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur}); - }, - endeffect: function(element) { - var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0 - new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity}); - }, - zindex: 1000, - revert: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } - }, arguments[1] || {}); - - this.element = $(element); - - if(options.handle && (typeof options.handle == 'string')) { - var h = Element.childrenWithClassName(this.element, options.handle, true); - if(h.length>0) this.handle = h[0]; - } - if(!this.handle) this.handle = $(options.handle); - if(!this.handle) this.handle = this.element; - - if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) - options.scroll = $(options.scroll); - - Element.makePositioned(this.element); // fix IE - - this.delta = this.currentDelta(); - this.options = options; - this.dragging = false; - - this.eventMouseDown = this.initDrag.bindAsEventListener(this); - Event.observe(this.handle, "mousedown", this.eventMouseDown); - - Draggables.register(this); - }, - - destroy: function() { - Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); - Draggables.unregister(this); - }, - - currentDelta: function() { - return([ - parseInt(Element.getStyle(this.element,'left') || '0'), - parseInt(Element.getStyle(this.element,'top') || '0')]); - }, - - initDrag: function(event) { - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - if(src.tagName && ( - src.tagName=='INPUT' || - src.tagName=='SELECT' || - src.tagName=='OPTION' || - src.tagName=='BUTTON' || - src.tagName=='TEXTAREA')) return; - - if(this.element._revert) { - this.element._revert.cancel(); - this.element._revert = null; - } - - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var pos = Position.cumulativeOffset(this.element); - this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); - - Draggables.activate(this); - Event.stop(event); - } - }, - - startDrag: function(event) { - this.dragging = true; - - if(this.options.zindex) { - this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); - this.element.style.zIndex = this.options.zindex; - } - - if(this.options.ghosting) { - this._clone = this.element.cloneNode(true); - Position.absolutize(this.element); - this.element.parentNode.insertBefore(this._clone, this.element); - } - - if(this.options.scroll) { - if (this.options.scroll == window) { - var where = this._getWindowScroll(this.options.scroll); - this.originalScrollLeft = where.left; - this.originalScrollTop = where.top; - } else { - this.originalScrollLeft = this.options.scroll.scrollLeft; - this.originalScrollTop = this.options.scroll.scrollTop; - } - } - - Draggables.notify('onStart', this, event); - if(this.options.starteffect) this.options.starteffect(this.element); - }, - - updateDrag: function(event, pointer) { - if(!this.dragging) this.startDrag(event); - Position.prepare(); - Droppables.show(pointer, this.element); - Draggables.notify('onDrag', this, event); - this.draw(pointer); - if(this.options.change) this.options.change(this); - - if(this.options.scroll) { - this.stopScrolling(); - - var p; - if (this.options.scroll == window) { - with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } - } else { - p = Position.page(this.options.scroll); - p[0] += this.options.scroll.scrollLeft; - p[1] += this.options.scroll.scrollTop; - p.push(p[0]+this.options.scroll.offsetWidth); - p.push(p[1]+this.options.scroll.offsetHeight); - } - var speed = [0,0]; - if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); - if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); - if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); - if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); - this.startScrolling(speed); - } - - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); - - Event.stop(event); - }, - - finishDrag: function(event, success) { - this.dragging = false; - - if(this.options.ghosting) { - Position.relativize(this.element); - Element.remove(this._clone); - this._clone = null; - } - - if(success) Droppables.fire(event, this.element); - Draggables.notify('onEnd', this, event); - - var revert = this.options.revert; - if(revert && typeof revert == 'function') revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - this.options.reverteffect(this.element, - d[1]-this.delta[1], d[0]-this.delta[0]); - } else { - this.delta = d; - } - - if(this.options.zindex) - this.element.style.zIndex = this.originalZ; - - if(this.options.endeffect) - this.options.endeffect(this.element); - - Draggables.deactivate(this); - Droppables.reset(); - }, - - keyPress: function(event) { - if(event.keyCode!=Event.KEY_ESC) return; - this.finishDrag(event, false); - Event.stop(event); - }, - - endDrag: function(event) { - if(!this.dragging) return; - this.stopScrolling(); - this.finishDrag(event, true); - Event.stop(event); - }, - - draw: function(point) { - var pos = Position.cumulativeOffset(this.element); - var d = this.currentDelta(); - pos[0] -= d[0]; pos[1] -= d[1]; - - if(this.options.scroll && (this.options.scroll != window)) { - pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; - pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; - } - - var p = [0,1].map(function(i){ - return (point[i]-pos[i]-this.offset[i]) - }.bind(this)); - - if(this.options.snap) { - if(typeof this.options.snap == 'function') { - p = this.options.snap(p[0],p[1],this); - } else { - if(this.options.snap instanceof Array) { - p = p.map( function(v, i) { - return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) - } else { - p = p.map( function(v) { - return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) - } - }} - - var style = this.element.style; - if((!this.options.constraint) || (this.options.constraint=='horizontal')) - style.left = p[0] + "px"; - if((!this.options.constraint) || (this.options.constraint=='vertical')) - style.top = p[1] + "px"; - if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering - }, - - stopScrolling: function() { - if(this.scrollInterval) { - clearInterval(this.scrollInterval); - this.scrollInterval = null; - Draggables._lastScrollPointer = null; - } - }, - - startScrolling: function(speed) { - this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; - this.lastScrolled = new Date(); - this.scrollInterval = setInterval(this.scroll.bind(this), 10); - }, - - scroll: function() { - var current = new Date(); - var delta = current - this.lastScrolled; - this.lastScrolled = current; - if(this.options.scroll == window) { - with (this._getWindowScroll(this.options.scroll)) { - if (this.scrollSpeed[0] || this.scrollSpeed[1]) { - var d = delta / 1000; - this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); - } - } - } else { - this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; - this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; - } - - Position.prepare(); - Droppables.show(Draggables._lastPointer, this.element); - Draggables.notify('onDrag', this); - Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); - Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; - Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; - if (Draggables._lastScrollPointer[0] < 0) - Draggables._lastScrollPointer[0] = 0; - if (Draggables._lastScrollPointer[1] < 0) - Draggables._lastScrollPointer[1] = 0; - this.draw(Draggables._lastScrollPointer); - - if(this.options.change) this.options.change(this); - }, - - _getWindowScroll: function(w) { - var T, L, W, H; - with (w.document) { - if (w.document.documentElement && documentElement.scrollTop) { - T = documentElement.scrollTop; - L = documentElement.scrollLeft; - } else if (w.document.body) { - T = body.scrollTop; - L = body.scrollLeft; - } - if (w.innerWidth) { - W = w.innerWidth; - H = w.innerHeight; - } else if (w.document.documentElement && documentElement.clientWidth) { - W = documentElement.clientWidth; - H = documentElement.clientHeight; - } else { - W = body.offsetWidth; - H = body.offsetHeight - } - } - return { top: T, left: L, width: W, height: H }; - } -} - -/*--------------------------------------------------------------------------*/ - -var SortableObserver = Class.create(); -SortableObserver.prototype = { - initialize: function(element, observer) { - this.element = $(element); - this.observer = observer; - this.lastValue = Sortable.serialize(this.element); - }, - - onStart: function() { - this.lastValue = Sortable.serialize(this.element); - }, - - onEnd: function() { - Sortable.unmark(); - if(this.lastValue != Sortable.serialize(this.element)) - this.observer(this.element) - } -} - -var Sortable = { - sortables: {}, - - _findRootElement: function(element) { - while (element.tagName != "BODY") { - if(element.id && Sortable.sortables[element.id]) return element; - element = element.parentNode; - } - }, - - options: function(element) { - element = Sortable._findRootElement($(element)); - if(!element) return; - return Sortable.sortables[element.id]; - }, - - destroy: function(element){ - var s = Sortable.options(element); - - if(s) { - Draggables.removeObserver(s.element); - s.droppables.each(function(d){ Droppables.remove(d) }); - s.draggables.invoke('destroy'); - - delete Sortable.sortables[s.element.id]; - } - }, - - create: function(element) { - element = $(element); - var options = Object.extend({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, - treeTag: 'ul', - overlap: 'vertical', // one of 'vertical', 'horizontal' - constraint: 'vertical', // one of 'vertical', 'horizontal', false - containment: element, // also takes array of elements (or id's); or false - handle: false, // or a CSS class - only: false, - hoverclass: null, - ghosting: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - format: /^[^_]*_(.*)$/, - onChange: Prototype.emptyFunction, - onUpdate: Prototype.emptyFunction - }, arguments[1] || {}); - - // clear any old sortable with same element - this.destroy(element); - - // build options for the draggables - var options_for_draggable = { - revert: true, - scroll: options.scroll, - scrollSpeed: options.scrollSpeed, - scrollSensitivity: options.scrollSensitivity, - ghosting: options.ghosting, - constraint: options.constraint, - handle: options.handle }; - - if(options.starteffect) - options_for_draggable.starteffect = options.starteffect; - - if(options.reverteffect) - options_for_draggable.reverteffect = options.reverteffect; - else - if(options.ghosting) options_for_draggable.reverteffect = function(element) { - element.style.top = 0; - element.style.left = 0; - }; - - if(options.endeffect) - options_for_draggable.endeffect = options.endeffect; - - if(options.zindex) - options_for_draggable.zindex = options.zindex; - - // build options for the droppables - var options_for_droppable = { - overlap: options.overlap, - containment: options.containment, - tree: options.tree, - hoverclass: options.hoverclass, - onHover: Sortable.onHover - //greedy: !options.dropOnEmpty - } - - var options_for_tree = { - onHover: Sortable.onEmptyHover, - overlap: options.overlap, - containment: options.containment, - hoverclass: options.hoverclass - } - - // fix for gecko engine - Element.cleanWhitespace(element); - - options.draggables = []; - options.droppables = []; - - // drop on empty handling - if(options.dropOnEmpty || options.tree) { - Droppables.add(element, options_for_tree); - options.droppables.push(element); - } - - (this.findElements(element, options) || []).each( function(e) { - // handles are per-draggable - var handle = options.handle ? - Element.childrenWithClassName(e, options.handle)[0] : e; - options.draggables.push( - new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); - Droppables.add(e, options_for_droppable); - if(options.tree) e.treeNode = element; - options.droppables.push(e); - }); - - if(options.tree) { - (Sortable.findTreeElements(element, options) || []).each( function(e) { - Droppables.add(e, options_for_tree); - e.treeNode = element; - options.droppables.push(e); - }); - } - - // keep reference - this.sortables[element.id] = options; - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.tag); - }, - - findTreeElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.treeTag); - }, - - onHover: function(element, dropon, overlap) { - if(Element.isParent(dropon, element)) return; - - if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { - return; - } else if(overlap>0.5) { - Sortable.mark(dropon, 'before'); - if(dropon.previousSibling != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, dropon); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } else { - Sortable.mark(dropon, 'after'); - var nextElement = dropon.nextSibling || null; - if(nextElement != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, nextElement); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } - }, - - onEmptyHover: function(element, dropon, overlap) { - var oldParentNode = element.parentNode; - var droponOptions = Sortable.options(dropon); - - if(!Element.isParent(dropon, element)) { - var index; - - var children = Sortable.findElements(dropon, {tag: droponOptions.tag}); - var child = null; - - if(children) { - var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); - - for (index = 0; index < children.length; index += 1) { - if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { - offset -= Element.offsetSize (children[index], droponOptions.overlap); - } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { - child = index + 1 < children.length ? children[index + 1] : null; - break; - } else { - child = children[index]; - break; - } - } - } - - dropon.insertBefore(element, child); - - Sortable.options(oldParentNode).onChange(element); - droponOptions.onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Element.hide(Sortable._marker); - }, - - mark: function(dropon, position) { - // mark on ghosting only - var sortable = Sortable.options(dropon.parentNode); - if(sortable && !sortable.ghosting) return; - - if(!Sortable._marker) { - Sortable._marker = $('dropmarker') || document.createElement('DIV'); - Element.hide(Sortable._marker); - Element.addClassName(Sortable._marker, 'dropmarker'); - Sortable._marker.style.position = 'absolute'; - document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } - var offsets = Position.cumulativeOffset(dropon); - Sortable._marker.style.left = offsets[0] + 'px'; - Sortable._marker.style.top = offsets[1] + 'px'; - - if(position=='after') - if(sortable.overlap == 'horizontal') - Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; - else - Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; - - Element.show(Sortable._marker); - }, - - _tree: function(element, options, parent) { - var children = Sortable.findElements(element, options) || []; - - for (var i = 0; i < children.length; ++i) { - var match = children[i].id.match(options.format); - - if (!match) continue; - - var child = { - id: encodeURIComponent(match ? match[1] : null), - element: element, - parent: parent, - children: new Array, - position: parent.children.length, - container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) - } - - /* Get the element containing the children and recurse over it */ - if (child.container) - this._tree(child.container, options, child) - - parent.children.push (child); - } - - return parent; - }, - - /* Finds the first element of the given tag type within a parent element. - Used for finding the first LI[ST] within a L[IST]I[TEM].*/ - _findChildrenElement: function (element, containerTag) { - if (element && element.hasChildNodes) - for (var i = 0; i < element.childNodes.length; ++i) - if (element.childNodes[i].tagName == containerTag) - return element.childNodes[i]; - - return null; - }, - - tree: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - treeTag: sortableOptions.treeTag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format - }, arguments[1] || {}); - - var root = { - id: null, - parent: null, - children: new Array, - container: element, - position: 0 - } - - return Sortable._tree (element, options, root); - }, - - /* Construct a [i] index for a particular node */ - _constructIndex: function(node) { - var index = ''; - do { - if (node.id) index = '[' + node.position + ']' + index; - } while ((node = node.parent) != null); - return index; - }, - - sequence: function(element) { - element = $(element); - var options = Object.extend(this.options(element), arguments[1] || {}); - - return $(this.findElements(element, options) || []).map( function(item) { - return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; - }); - }, - - setSequence: function(element, new_sequence) { - element = $(element); - var options = Object.extend(this.options(element), arguments[2] || {}); - - var nodeMap = {}; - this.findElements(element, options).each( function(n) { - if (n.id.match(options.format)) - nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; - n.parentNode.removeChild(n); - }); - - new_sequence.each(function(ident) { - var n = nodeMap[ident]; - if (n) { - n[1].appendChild(n[0]); - delete nodeMap[ident]; - } - }); - }, - - serialize: function(element) { - element = $(element); - var options = Object.extend(Sortable.options(element), arguments[1] || {}); - var name = encodeURIComponent( - (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); - - if (options.tree) { - return Sortable.tree(element, arguments[1]).children.map( function (item) { - return [name + Sortable._constructIndex(item) + "=" + - encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); - }).flatten().join('&'); - } else { - return Sortable.sequence(element, arguments[1]).map( function(item) { - return name + "[]=" + encodeURIComponent(item); - }).join('&'); - } - } -} - -/* Returns true if child is contained within element */ -Element.isParent = function(child, element) { - if (!child.parentNode || child == element) return false; - - if (child.parentNode == element) return true; - - return Element.isParent(child.parentNode, element); -} - -Element.findChildren = function(element, only, recursive, tagName) { - if(!element.hasChildNodes()) return null; - tagName = tagName.toUpperCase(); - if(only) only = [only].flatten(); - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==tagName && - (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) - elements.push(e); - if(recursive) { - var grandchildren = Element.findChildren(e, only, recursive, tagName); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : []); -} - -Element.offsetSize = function (element, type) { - if (type == 'vertical' || type == 'height') - return element.offsetHeight; - else - return element.offsetWidth; -} \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/effects.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/effects.js deleted file mode 100644 index 0864323e..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/effects.js +++ /dev/null @@ -1,958 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// Contributors: -// Justin Palmer (http://encytemedia.com/) -// Mark Pilgrim (http://diveintomark.org/) -// Martin Bialasinki -// -// See scriptaculous.js for full license. - -// converts rgb() and #xxx to #xxxxxx format, -// returns self (or first argument) if not convertable -String.prototype.parseColor = function() { - var color = '#'; - if(this.slice(0,4) == 'rgb(') { - var cols = this.slice(4,this.length-1).split(','); - var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); - } else { - if(this.slice(0,1) == '#') { - if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); - if(this.length==7) color = this.toLowerCase(); - } - } - return(color.length==7 ? color : (arguments[0] || this)); -} - -/*--------------------------------------------------------------------------*/ - -Element.collectTextNodes = function(element) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); - }).flatten().join(''); -} - -Element.collectTextNodesIgnoreClass = function(element, className) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? - Element.collectTextNodesIgnoreClass(node, className) : '')); - }).flatten().join(''); -} - -Element.setContentZoom = function(element, percent) { - element = $(element); - Element.setStyle(element, {fontSize: (percent/100) + 'em'}); - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); -} - -Element.getOpacity = function(element){ - var opacity; - if (opacity = Element.getStyle(element, 'opacity')) - return parseFloat(opacity); - if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) - if(opacity[1]) return parseFloat(opacity[1]) / 100; - return 1.0; -} - -Element.setOpacity = function(element, value){ - element= $(element); - if (value == 1){ - Element.setStyle(element, { opacity: - (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? - 0.999999 : null }); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); - } else { - if(value < 0.00001) value = 0; - Element.setStyle(element, {opacity: value}); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, - { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + - 'alpha(opacity='+value*100+')' }); - } -} - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -} - -Element.childrenWithClassName = function(element, className, findFirst) { - var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)"); - var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { - return (c.className && c.className.match(classNameRegExp)); - }); - if(!results) results = []; - return results; -} - -Element.forceRerendering = function(element) { - try { - element = $(element); - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch(e) { } -}; - -/*--------------------------------------------------------------------------*/ - -Array.prototype.call = function() { - var args = arguments; - this.each(function(f){ f.apply(this, args) }); -} - -/*--------------------------------------------------------------------------*/ - -var Effect = { - tagifyText: function(element) { - var tagifyStyle = 'position:relative'; - if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; - element = $(element); - $A(element.childNodes).each( function(child) { - if(child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - Builder.node('span',{style: tagifyStyle}, - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - if(((typeof element == 'object') || - (typeof element == 'function')) && - (element.length)) - elements = element; - else - elements = $(element).childNodes; - - var options = Object.extend({ - speed: 0.1, - delay: 0.0 - }, arguments[2] || {}); - var masterDelay = options.delay; - - $A(elements).each( function(element, index) { - new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); - }); - }, - PAIRS: { - 'slide': ['SlideDown','SlideUp'], - 'blind': ['BlindDown','BlindUp'], - 'appear': ['Appear','Fade'] - }, - toggle: function(element, effect) { - element = $(element); - effect = (effect || 'appear').toLowerCase(); - var options = Object.extend({ - queue: { position:'end', scope:(element.id || 'global'), limit: 1 } - }, arguments[2] || {}); - Effect[element.visible() ? - Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); - } -}; - -var Effect2 = Effect; // deprecated - -/* ------------- transitions ------------- */ - -Effect.Transitions = {} - -Effect.Transitions.linear = function(pos) { - return pos; -} -Effect.Transitions.sinoidal = function(pos) { - return (-Math.cos(pos*Math.PI)/2) + 0.5; -} -Effect.Transitions.reverse = function(pos) { - return 1-pos; -} -Effect.Transitions.flicker = function(pos) { - return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; -} -Effect.Transitions.wobble = function(pos) { - return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; -} -Effect.Transitions.pulse = function(pos) { - return (Math.floor(pos*10) % 2 == 0 ? - (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); -} -Effect.Transitions.none = function(pos) { - return 0; -} -Effect.Transitions.full = function(pos) { - return 1; -} - -/* ------------- core effects ------------- */ - -Effect.ScopedQueue = Class.create(); -Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { - initialize: function() { - this.effects = []; - this.interval = null; - }, - _each: function(iterator) { - this.effects._each(iterator); - }, - add: function(effect) { - var timestamp = new Date().getTime(); - - var position = (typeof effect.options.queue == 'string') ? - effect.options.queue : effect.options.queue.position; - - switch(position) { - case 'front': - // move unstarted effects after this effect - this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { - e.startOn += effect.finishOn; - e.finishOn += effect.finishOn; - }); - break; - case 'end': - // start effect after last queued effect has finished - timestamp = this.effects.pluck('finishOn').max() || timestamp; - break; - } - - effect.startOn += timestamp; - effect.finishOn += timestamp; - - if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) - this.effects.push(effect); - - if(!this.interval) - this.interval = setInterval(this.loop.bind(this), 40); - }, - remove: function(effect) { - this.effects = this.effects.reject(function(e) { return e==effect }); - if(this.effects.length == 0) { - clearInterval(this.interval); - this.interval = null; - } - }, - loop: function() { - var timePos = new Date().getTime(); - this.effects.invoke('loop', timePos); - } -}); - -Effect.Queues = { - instances: $H(), - get: function(queueName) { - if(typeof queueName != 'string') return queueName; - - if(!this.instances[queueName]) - this.instances[queueName] = new Effect.ScopedQueue(); - - return this.instances[queueName]; - } -} -Effect.Queue = Effect.Queues.get('global'); - -Effect.DefaultOptions = { - transition: Effect.Transitions.sinoidal, - duration: 1.0, // seconds - fps: 25.0, // max. 25fps due to Effect.Queue implementation - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' -} - -Effect.Base = function() {}; -Effect.Base.prototype = { - position: null, - start: function(options) { - this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); - this.currentFrame = 0; - this.state = 'idle'; - this.startOn = this.options.delay*1000; - this.finishOn = this.startOn + (this.options.duration*1000); - this.event('beforeStart'); - if(!this.options.sync) - Effect.Queues.get(typeof this.options.queue == 'string' ? - 'global' : this.options.queue.scope).add(this); - }, - loop: function(timePos) { - if(timePos >= this.startOn) { - if(timePos >= this.finishOn) { - this.render(1.0); - this.cancel(); - this.event('beforeFinish'); - if(this.finish) this.finish(); - this.event('afterFinish'); - return; - } - var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); - var frame = Math.round(pos * this.options.fps * this.options.duration); - if(frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - render: function(pos) { - if(this.state == 'idle') { - this.state = 'running'; - this.event('beforeSetup'); - if(this.setup) this.setup(); - this.event('afterSetup'); - } - if(this.state == 'running') { - if(this.options.transition) pos = this.options.transition(pos); - pos *= (this.options.to-this.options.from); - pos += this.options.from; - this.position = pos; - this.event('beforeUpdate'); - if(this.update) this.update(pos); - this.event('afterUpdate'); - } - }, - cancel: function() { - if(!this.options.sync) - Effect.Queues.get(typeof this.options.queue == 'string' ? - 'global' : this.options.queue.scope).remove(this); - this.state = 'finished'; - }, - event: function(eventName) { - if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); - if(this.options[eventName]) this.options[eventName](this); - }, - inspect: function() { - return '#'; - } -} - -Effect.Parallel = Class.create(); -Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { - initialize: function(effects) { - this.effects = effects || []; - this.start(arguments[1]); - }, - update: function(position) { - this.effects.invoke('render', position); - }, - finish: function(position) { - this.effects.each( function(effect) { - effect.render(1.0); - effect.cancel(); - effect.event('beforeFinish'); - if(effect.finish) effect.finish(position); - effect.event('afterFinish'); - }); - } -}); - -Effect.Opacity = Class.create(); -Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - // make this work on IE on elements without 'layout' - if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) - this.element.setStyle({zoom: 1}); - var options = Object.extend({ - from: this.element.getOpacity() || 0.0, - to: 1.0 - }, arguments[1] || {}); - this.start(options); - }, - update: function(position) { - this.element.setOpacity(position); - } -}); - -Effect.Move = Class.create(); -Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - var options = Object.extend({ - x: 0, - y: 0, - mode: 'relative' - }, arguments[1] || {}); - this.start(options); - }, - setup: function() { - // Bug in Opera: Opera returns the "real" position of a static element or - // relative element that does not have top/left explicitly set. - // ==> Always set top and left for position relative elements in your stylesheets - // (to 0 if you do not need them) - this.element.makePositioned(); - this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); - this.originalTop = parseFloat(this.element.getStyle('top') || '0'); - if(this.options.mode == 'absolute') { - // absolute movement, so we need to calc deltaX and deltaY - this.options.x = this.options.x - this.originalLeft; - this.options.y = this.options.y - this.originalTop; - } - }, - update: function(position) { - this.element.setStyle({ - left: this.options.x * position + this.originalLeft + 'px', - top: this.options.y * position + this.originalTop + 'px' - }); - } -}); - -// for backwards compatibility -Effect.MoveBy = function(element, toTop, toLeft) { - return new Effect.Move(element, - Object.extend({ x: toLeft, y: toTop }, arguments[3] || {})); -}; - -Effect.Scale = Class.create(); -Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { - initialize: function(element, percent) { - this.element = $(element) - var options = Object.extend({ - scaleX: true, - scaleY: true, - scaleContent: true, - scaleFromCenter: false, - scaleMode: 'box', // 'box' or 'contents' or {} with provided values - scaleFrom: 100.0, - scaleTo: percent - }, arguments[2] || {}); - this.start(options); - }, - setup: function() { - this.restoreAfterFinish = this.options.restoreAfterFinish || false; - this.elementPositioning = this.element.getStyle('position'); - - this.originalStyle = {}; - ['top','left','width','height','fontSize'].each( function(k) { - this.originalStyle[k] = this.element.style[k]; - }.bind(this)); - - this.originalTop = this.element.offsetTop; - this.originalLeft = this.element.offsetLeft; - - var fontSize = this.element.getStyle('font-size') || '100%'; - ['em','px','%'].each( function(fontSizeType) { - if(fontSize.indexOf(fontSizeType)>0) { - this.fontSize = parseFloat(fontSize); - this.fontSizeType = fontSizeType; - } - }.bind(this)); - - this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; - - this.dims = null; - if(this.options.scaleMode=='box') - this.dims = [this.element.offsetHeight, this.element.offsetWidth]; - if(/^content/.test(this.options.scaleMode)) - this.dims = [this.element.scrollHeight, this.element.scrollWidth]; - if(!this.dims) - this.dims = [this.options.scaleMode.originalHeight, - this.options.scaleMode.originalWidth]; - }, - update: function(position) { - var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); - if(this.options.scaleContent && this.fontSize) - this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); - this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); - }, - finish: function(position) { - if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); - }, - setDimensions: function(height, width) { - var d = {}; - if(this.options.scaleX) d.width = width + 'px'; - if(this.options.scaleY) d.height = height + 'px'; - if(this.options.scaleFromCenter) { - var topd = (height - this.dims[0])/2; - var leftd = (width - this.dims[1])/2; - if(this.elementPositioning == 'absolute') { - if(this.options.scaleY) d.top = this.originalTop-topd + 'px'; - if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; - } else { - if(this.options.scaleY) d.top = -topd + 'px'; - if(this.options.scaleX) d.left = -leftd + 'px'; - } - } - this.element.setStyle(d); - } -}); - -Effect.Highlight = Class.create(); -Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if(this.element.getStyle('display')=='none') { this.cancel(); return; } - // Disable background image during the effect - this.oldStyle = { - backgroundImage: this.element.getStyle('background-image') }; - this.element.setStyle({backgroundImage: 'none'}); - if(!this.options.endcolor) - this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); - if(!this.options.restorecolor) - this.options.restorecolor = this.element.getStyle('background-color'); - // init color calculations - this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); - this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); - }, - update: function(position) { - this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); - }, - finish: function() { - this.element.setStyle(Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -Effect.ScrollTo = Class.create(); -Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - this.start(arguments[1] || {}); - }, - setup: function() { - Position.prepare(); - var offsets = Position.cumulativeOffset(this.element); - if(this.options.offset) offsets[1] += this.options.offset; - var max = window.innerHeight ? - window.height - window.innerHeight : - document.body.scrollHeight - - (document.documentElement.clientHeight ? - document.documentElement.clientHeight : document.body.clientHeight); - this.scrollStart = Position.deltaY; - this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; - }, - update: function(position) { - Position.prepare(); - window.scrollTo(Position.deltaX, - this.scrollStart + (position*this.delta)); - } -}); - -/* ------------- combination effects ------------- */ - -Effect.Fade = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - var options = Object.extend({ - from: element.getOpacity() || 1.0, - to: 0.0, - afterFinishInternal: function(effect) { - if(effect.options.to!=0) return; - effect.element.hide(); - effect.element.setStyle({opacity: oldOpacity}); - }}, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Appear = function(element) { - element = $(element); - var options = Object.extend({ - from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), - to: 1.0, - // force Safari to render floated elements properly - afterFinishInternal: function(effect) { - effect.element.forceRerendering(); - }, - beforeSetup: function(effect) { - effect.element.setOpacity(effect.options.from); - effect.element.show(); - }}, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Puff = function(element) { - element = $(element); - var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') }; - return new Effect.Parallel( - [ new Effect.Scale(element, 200, - { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], - Object.extend({ duration: 1.0, - beforeSetupInternal: function(effect) { - effect.effects[0].element.setStyle({position: 'absolute'}); }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide(); - effect.effects[0].element.setStyle(oldStyle); } - }, arguments[1] || {}) - ); -} - -Effect.BlindUp = function(element) { - element = $(element); - element.makeClipping(); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { - effect.element.hide(); - effect.element.undoClipping(); - } - }, arguments[1] || {}) - ); -} - -Effect.BlindDown = function(element) { - element = $(element); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, - Object.extend({ scaleContent: false, - scaleX: false, - scaleFrom: 0, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makeClipping(); - effect.element.setStyle({height: '0px'}); - effect.element.show(); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping(); - } - }, arguments[1] || {}) - ); -} - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - return new Effect.Appear(element, { - duration: 0.4, - from: 0, - transition: Effect.Transitions.flicker, - afterFinishInternal: function(effect) { - new Effect.Scale(effect.element, 1, { - duration: 0.3, scaleFromCenter: true, - scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makePositioned(); - effect.element.makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide(); - effect.element.undoClipping(); - effect.element.undoPositioned(); - effect.element.setStyle({opacity: oldOpacity}); - } - }) - } - }); -} - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left'), - opacity: element.getInlineOpacity() }; - return new Effect.Parallel( - [ new Effect.Move(element, {x: 0, y: 100, sync: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 }) ], - Object.extend( - { duration: 0.5, - beforeSetup: function(effect) { - effect.effects[0].element.makePositioned(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide(); - effect.effects[0].element.undoPositioned(); - effect.effects[0].element.setStyle(oldStyle); - } - }, arguments[1] || {})); -} - -Effect.Shake = function(element) { - element = $(element); - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left') }; - return new Effect.Move(element, - { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { - effect.element.undoPositioned(); - effect.element.setStyle(oldStyle); - }}) }}) }}) }}) }}) }}); -} - -Effect.SlideDown = function(element) { - element = $(element); - element.cleanWhitespace(); - // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = $(element.firstChild).getStyle('bottom'); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, - scaleFrom: window.opera ? 0 : 1, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makePositioned(); - effect.element.firstChild.makePositioned(); - if(window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping(); - effect.element.setStyle({height: '0px'}); - effect.element.show(); }, - afterUpdateInternal: function(effect) { - effect.element.firstChild.setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping(); - // IE will crash if child is undoPositioned first - if(/MSIE/.test(navigator.userAgent)){ - effect.element.undoPositioned(); - effect.element.firstChild.undoPositioned(); - }else{ - effect.element.firstChild.undoPositioned(); - effect.element.undoPositioned(); - } - effect.element.firstChild.setStyle({bottom: oldInnerBottom}); } - }, arguments[1] || {}) - ); -} - -Effect.SlideUp = function(element) { - element = $(element); - element.cleanWhitespace(); - var oldInnerBottom = $(element.firstChild).getStyle('bottom'); - return new Effect.Scale(element, window.opera ? 0 : 1, - Object.extend({ scaleContent: false, - scaleX: false, - scaleMode: 'box', - scaleFrom: 100, - restoreAfterFinish: true, - beforeStartInternal: function(effect) { - effect.element.makePositioned(); - effect.element.firstChild.makePositioned(); - if(window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping(); - effect.element.show(); }, - afterUpdateInternal: function(effect) { - effect.element.firstChild.setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, - afterFinishInternal: function(effect) { - effect.element.hide(); - effect.element.undoClipping(); - effect.element.firstChild.undoPositioned(); - effect.element.undoPositioned(); - effect.element.setStyle({bottom: oldInnerBottom}); } - }, arguments[1] || {}) - ); -} - -// Bug in opera makes the TD containing this element expand for a instance after finish -Effect.Squish = function(element) { - return new Effect.Scale(element, window.opera ? 1 : 0, - { restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makeClipping(effect.element); }, - afterFinishInternal: function(effect) { - effect.element.hide(effect.element); - effect.element.undoClipping(effect.element); } - }); -} - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.full - }, arguments[1] || {}); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var initialMoveX, initialMoveY; - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - initialMoveX = initialMoveY = moveX = moveY = 0; - break; - case 'top-right': - initialMoveX = dims.width; - initialMoveY = moveY = 0; - moveX = -dims.width; - break; - case 'bottom-left': - initialMoveX = moveX = 0; - initialMoveY = dims.height; - moveY = -dims.height; - break; - case 'bottom-right': - initialMoveX = dims.width; - initialMoveY = dims.height; - moveX = -dims.width; - moveY = -dims.height; - break; - case 'center': - initialMoveX = dims.width / 2; - initialMoveY = dims.height / 2; - moveX = -dims.width / 2; - moveY = -dims.height / 2; - break; - } - - return new Effect.Move(element, { - x: initialMoveX, - y: initialMoveY, - duration: 0.01, - beforeSetup: function(effect) { - effect.element.hide(); - effect.element.makeClipping(); - effect.element.makePositioned(); - }, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), - new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), - new Effect.Scale(effect.element, 100, { - scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, - sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) - ], Object.extend({ - beforeSetup: function(effect) { - effect.effects[0].element.setStyle({height: '0px'}); - effect.effects[0].element.show(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.undoClipping(); - effect.effects[0].element.undoPositioned(); - effect.effects[0].element.setStyle(oldStyle); - } - }, options) - ) - } - }); -} - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.none - }, arguments[1] || {}); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - moveX = moveY = 0; - break; - case 'top-right': - moveX = dims.width; - moveY = 0; - break; - case 'bottom-left': - moveX = 0; - moveY = dims.height; - break; - case 'bottom-right': - moveX = dims.width; - moveY = dims.height; - break; - case 'center': - moveX = dims.width / 2; - moveY = dims.height / 2; - break; - } - - return new Effect.Parallel( - [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), - new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), - new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) - ], Object.extend({ - beforeStartInternal: function(effect) { - effect.effects[0].element.makePositioned(); - effect.effects[0].element.makeClipping(); }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide(); - effect.effects[0].element.undoClipping(); - effect.effects[0].element.undoPositioned(); - effect.effects[0].element.setStyle(oldStyle); } - }, options) - ); -} - -Effect.Pulsate = function(element) { - element = $(element); - var options = arguments[1] || {}; - var oldOpacity = element.getInlineOpacity(); - var transition = options.transition || Effect.Transitions.sinoidal; - var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; - reverser.bind(transition); - return new Effect.Opacity(element, - Object.extend(Object.extend({ duration: 3.0, from: 0, - afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } - }, options), {transition: reverser})); -} - -Effect.Fold = function(element) { - element = $(element); - var oldStyle = { - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height }; - Element.makeClipping(element); - return new Effect.Scale(element, 5, Object.extend({ - scaleContent: false, - scaleX: false, - afterFinishInternal: function(effect) { - new Effect.Scale(element, 1, { - scaleContent: false, - scaleY: false, - afterFinishInternal: function(effect) { - effect.element.hide(); - effect.element.undoClipping(); - effect.element.setStyle(oldStyle); - } }); - }}, arguments[1] || {})); -}; - -['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', - 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( - function(f) { Element.Methods[f] = Element[f]; } -); - -Element.Methods.visualEffect = function(element, effect, options) { - s = effect.gsub(/_/, '-').camelize(); - effect_class = s.charAt(0).toUpperCase() + s.substring(1); - new Effect[effect_class](element, options); - return $(element); -}; - -Element.addMethods(); \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/scriptaculous.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/scriptaculous.js deleted file mode 100644 index f61fc57f..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/scriptaculous.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -var Scriptaculous = { - Version: '1.6.1', - require: function(libraryName) { - // inserting via DOM fails in Safari 2.0, so brute force approach - document.write(''); - }, - load: function() { - if((typeof Prototype=='undefined') || - (typeof Element == 'undefined') || - (typeof Element.Methods=='undefined') || - parseFloat(Prototype.Version.split(".")[0] + "." + - Prototype.Version.split(".")[1]) < 1.5) - throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0"); - - $A(document.getElementsByTagName("script")).findAll( function(s) { - return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) - }).each( function(s) { - var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); - var includes = s.src.match(/\?.*load=([a-z,]*)/); - (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each( - function(include) { Scriptaculous.require(path+include+'.js') }); - }); - } -} - -Scriptaculous.load(); \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/slider.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/slider.js deleted file mode 100644 index c0f1fc01..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/slider.js +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2005 Marty Haught, Thomas Fuchs -// -// See http://script.aculo.us for more info -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -if(!Control) var Control = {}; -Control.Slider = Class.create(); - -// options: -// axis: 'vertical', or 'horizontal' (default) -// -// callbacks: -// onChange(value) -// onSlide(value) -Control.Slider.prototype = { - initialize: function(handle, track, options) { - var slider = this; - - if(handle instanceof Array) { - this.handles = handle.collect( function(e) { return $(e) }); - } else { - this.handles = [$(handle)]; - } - - this.track = $(track); - this.options = options || {}; - - this.axis = this.options.axis || 'horizontal'; - this.increment = this.options.increment || 1; - this.step = parseInt(this.options.step || '1'); - this.range = this.options.range || $R(0,1); - - this.value = 0; // assure backwards compat - this.values = this.handles.map( function() { return 0 }); - this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; - this.options.startSpan = $(this.options.startSpan || null); - this.options.endSpan = $(this.options.endSpan || null); - - this.restricted = this.options.restricted || false; - - this.maximum = this.options.maximum || this.range.end; - this.minimum = this.options.minimum || this.range.start; - - // Will be used to align the handle onto the track, if necessary - this.alignX = parseInt(this.options.alignX || '0'); - this.alignY = parseInt(this.options.alignY || '0'); - - this.trackLength = this.maximumOffset() - this.minimumOffset(); - this.handleLength = this.isVertical() ? this.handles[0].offsetHeight : this.handles[0].offsetWidth; - - this.active = false; - this.dragging = false; - this.disabled = false; - - if(this.options.disabled) this.setDisabled(); - - // Allowed values array - this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; - if(this.allowedValues) { - this.minimum = this.allowedValues.min(); - this.maximum = this.allowedValues.max(); - } - - this.eventMouseDown = this.startDrag.bindAsEventListener(this); - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.update.bindAsEventListener(this); - - // Initialize handles in reverse (make sure first handle is active) - this.handles.each( function(h,i) { - i = slider.handles.length-1-i; - slider.setValue(parseFloat( - (slider.options.sliderValue instanceof Array ? - slider.options.sliderValue[i] : slider.options.sliderValue) || - slider.range.start), i); - Element.makePositioned(h); // fix IE - Event.observe(h, "mousedown", slider.eventMouseDown); - }); - - Event.observe(this.track, "mousedown", this.eventMouseDown); - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - - this.initialized = true; - }, - dispose: function() { - var slider = this; - Event.stopObserving(this.track, "mousedown", this.eventMouseDown); - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - this.handles.each( function(h) { - Event.stopObserving(h, "mousedown", slider.eventMouseDown); - }); - }, - setDisabled: function(){ - this.disabled = true; - }, - setEnabled: function(){ - this.disabled = false; - }, - getNearestValue: function(value){ - if(this.allowedValues){ - if(value >= this.allowedValues.max()) return(this.allowedValues.max()); - if(value <= this.allowedValues.min()) return(this.allowedValues.min()); - - var offset = Math.abs(this.allowedValues[0] - value); - var newValue = this.allowedValues[0]; - this.allowedValues.each( function(v) { - var currentOffset = Math.abs(v - value); - if(currentOffset <= offset){ - newValue = v; - offset = currentOffset; - } - }); - return newValue; - } - if(value > this.range.end) return this.range.end; - if(value < this.range.start) return this.range.start; - return value; - }, - setValue: function(sliderValue, handleIdx){ - if(!this.active) { - this.activeHandle = this.handles[handleIdx]; - this.activeHandleIdx = handleIdx; - this.updateStyles(); - } - handleIdx = handleIdx || this.activeHandleIdx || 0; - if(this.initialized && this.restricted) { - if((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) - sliderValue = this.values[handleIdx+1]; - } - sliderValue = this.getNearestValue(sliderValue); - this.values[handleIdx] = sliderValue; - this.value = this.values[0]; // assure backwards compat - - this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = - this.translateToPx(sliderValue); - - this.drawSpans(); - if(!this.dragging || !this.event) this.updateFinished(); - }, - setValueBy: function(delta, handleIdx) { - this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, - handleIdx || this.activeHandleIdx || 0); - }, - translateToPx: function(value) { - return Math.round( - ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * - (value - this.range.start)) + "px"; - }, - translateToValue: function(offset) { - return ((offset/(this.trackLength-this.handleLength) * - (this.range.end-this.range.start)) + this.range.start); - }, - getRange: function(range) { - var v = this.values.sortBy(Prototype.K); - range = range || 0; - return $R(v[range],v[range+1]); - }, - minimumOffset: function(){ - return(this.isVertical() ? this.alignY : this.alignX); - }, - maximumOffset: function(){ - return(this.isVertical() ? - this.track.offsetHeight - this.alignY : this.track.offsetWidth - this.alignX); - }, - isVertical: function(){ - return (this.axis == 'vertical'); - }, - drawSpans: function() { - var slider = this; - if(this.spans) - $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); - if(this.options.startSpan) - this.setSpan(this.options.startSpan, - $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); - if(this.options.endSpan) - this.setSpan(this.options.endSpan, - $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); - }, - setSpan: function(span, range) { - if(this.isVertical()) { - span.style.top = this.translateToPx(range.start); - span.style.height = this.translateToPx(range.end - range.start + this.range.start); - } else { - span.style.left = this.translateToPx(range.start); - span.style.width = this.translateToPx(range.end - range.start + this.range.start); - } - }, - updateStyles: function() { - this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); - Element.addClassName(this.activeHandle, 'selected'); - }, - startDrag: function(event) { - if(Event.isLeftClick(event)) { - if(!this.disabled){ - this.active = true; - - var handle = Event.element(event); - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - if(handle==this.track) { - var offsets = Position.cumulativeOffset(this.track); - this.event = event; - this.setValue(this.translateToValue( - (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) - )); - var offsets = Position.cumulativeOffset(this.activeHandle); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } else { - // find the handle (prevents issues with Safari) - while((this.handles.indexOf(handle) == -1) && handle.parentNode) - handle = handle.parentNode; - - this.activeHandle = handle; - this.activeHandleIdx = this.handles.indexOf(this.activeHandle); - this.updateStyles(); - - var offsets = Position.cumulativeOffset(this.activeHandle); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } - } - Event.stop(event); - } - }, - update: function(event) { - if(this.active) { - if(!this.dragging) this.dragging = true; - this.draw(event); - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); - Event.stop(event); - } - }, - draw: function(event) { - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var offsets = Position.cumulativeOffset(this.track); - pointer[0] -= this.offsetX + offsets[0]; - pointer[1] -= this.offsetY + offsets[1]; - this.event = event; - this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); - if(this.initialized && this.options.onSlide) - this.options.onSlide(this.values.length>1 ? this.values : this.value, this); - }, - endDrag: function(event) { - if(this.active && this.dragging) { - this.finishDrag(event, true); - Event.stop(event); - } - this.active = false; - this.dragging = false; - }, - finishDrag: function(event, success) { - this.active = false; - this.dragging = false; - this.updateFinished(); - }, - updateFinished: function() { - if(this.initialized && this.options.onChange) - this.options.onChange(this.values.length>1 ? this.values : this.value, this); - this.event = null; - } -} \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/unittest.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/unittest.js deleted file mode 100644 index d2c2d817..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/unittest.js +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Jon Tirsen (http://www.tirsen.com) -// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -// experimental, Firefox-only -Event.simulateMouse = function(element, eventName) { - var options = Object.extend({ - pointerX: 0, - pointerY: 0, - buttons: 0 - }, arguments[2] || {}); - var oEvent = document.createEvent("MouseEvents"); - oEvent.initMouseEvent(eventName, true, true, document.defaultView, - options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, - false, false, false, false, 0, $(element)); - - if(this.mark) Element.remove(this.mark); - this.mark = document.createElement('div'); - this.mark.appendChild(document.createTextNode(" ")); - document.body.appendChild(this.mark); - this.mark.style.position = 'absolute'; - this.mark.style.top = options.pointerY + "px"; - this.mark.style.left = options.pointerX + "px"; - this.mark.style.width = "5px"; - this.mark.style.height = "5px;"; - this.mark.style.borderTop = "1px solid red;" - this.mark.style.borderLeft = "1px solid red;" - - if(this.step) - alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); - - $(element).dispatchEvent(oEvent); -}; - -// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2. -// You need to downgrade to 1.0.4 for now to get this working -// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much -Event.simulateKey = function(element, eventName) { - var options = Object.extend({ - ctrlKey: false, - altKey: false, - shiftKey: false, - metaKey: false, - keyCode: 0, - charCode: 0 - }, arguments[2] || {}); - - var oEvent = document.createEvent("KeyEvents"); - oEvent.initKeyEvent(eventName, true, true, window, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, - options.keyCode, options.charCode ); - $(element).dispatchEvent(oEvent); -}; - -Event.simulateKeys = function(element, command) { - for(var i=0; i

    ' + - '' + - '' + - '' + - '
    StatusTestMessage
    '; - this.logsummary = $('logsummary') - this.loglines = $('loglines'); - }, - _toHTML: function(txt) { - return txt.escapeHTML().replace(/\n/g,"
    "); - } -} - -Test.Unit.Runner = Class.create(); -Test.Unit.Runner.prototype = { - initialize: function(testcases) { - this.options = Object.extend({ - testLog: 'testlog' - }, arguments[1] || {}); - this.options.resultsURL = this.parseResultsURLQueryParameter(); - if (this.options.testLog) { - this.options.testLog = $(this.options.testLog) || null; - } - if(this.options.tests) { - this.tests = []; - for(var i = 0; i < this.options.tests.length; i++) { - if(/^test/.test(this.options.tests[i])) { - this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); - } - } - } else { - if (this.options.test) { - this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; - } else { - this.tests = []; - for(var testcase in testcases) { - if(/^test/.test(testcase)) { - this.tests.push(new Test.Unit.Testcase(testcase, testcases[testcase], testcases["setup"], testcases["teardown"])); - } - } - } - } - this.currentTest = 0; - this.logger = new Test.Unit.Logger(this.options.testLog); - setTimeout(this.runTests.bind(this), 1000); - }, - parseResultsURLQueryParameter: function() { - return window.location.search.parseQuery()["resultsURL"]; - }, - // Returns: - // "ERROR" if there was an error, - // "FAILURE" if there was a failure, or - // "SUCCESS" if there was neither - getResult: function() { - var hasFailure = false; - for(var i=0;i 0) { - return "ERROR"; - } - if (this.tests[i].failures > 0) { - hasFailure = true; - } - } - if (hasFailure) { - return "FAILURE"; - } else { - return "SUCCESS"; - } - }, - postResults: function() { - if (this.options.resultsURL) { - new Ajax.Request(this.options.resultsURL, - { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); - } - }, - runTests: function() { - var test = this.tests[this.currentTest]; - if (!test) { - // finished! - this.postResults(); - this.logger.summary(this.summary()); - return; - } - if(!test.isWaiting) { - this.logger.start(test.name); - } - test.run(); - if(test.isWaiting) { - this.logger.message("Waiting for " + test.timeToWait + "ms"); - setTimeout(this.runTests.bind(this), test.timeToWait || 1000); - } else { - this.logger.finish(test.status(), test.summary()); - this.currentTest++; - // tail recursive, hopefully the browser will skip the stackframe - this.runTests(); - } - }, - summary: function() { - var assertions = 0; - var failures = 0; - var errors = 0; - var messages = []; - for(var i=0;i 0) return 'failed'; - if (this.errors > 0) return 'error'; - return 'passed'; - }, - assert: function(expression) { - var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; - try { expression ? this.pass() : - this.fail(message); } - catch(e) { this.error(e); } - }, - assertEqual: function(expected, actual) { - var message = arguments[2] || "assertEqual"; - try { (expected == actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertEnumEqual: function(expected, actual) { - var message = arguments[2] || "assertEnumEqual"; - try { $A(expected).length == $A(actual).length && - expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? - this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + - ', actual ' + Test.Unit.inspect(actual)); } - catch(e) { this.error(e); } - }, - assertNotEqual: function(expected, actual) { - var message = arguments[2] || "assertNotEqual"; - try { (expected != actual) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertNull: function(obj) { - var message = arguments[1] || 'assertNull' - try { (obj==null) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } - catch(e) { this.error(e); } - }, - assertHidden: function(element) { - var message = arguments[1] || 'assertHidden'; - this.assertEqual("none", element.style.display, message); - }, - assertNotNull: function(object) { - var message = arguments[1] || 'assertNotNull'; - this.assert(object != null, message); - }, - assertInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertInstanceOf'; - try { - (actual instanceof expected) ? this.pass() : - this.fail(message + ": object was not an instance of the expected type"); } - catch(e) { this.error(e); } - }, - assertNotInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertNotInstanceOf'; - try { - !(actual instanceof expected) ? this.pass() : - this.fail(message + ": object was an instance of the not expected type"); } - catch(e) { this.error(e); } - }, - _isVisible: function(element) { - element = $(element); - if(!element.parentNode) return true; - this.assertNotNull(element); - if(element.style && Element.getStyle(element, 'display') == 'none') - return false; - - return this._isVisible(element.parentNode); - }, - assertNotVisible: function(element) { - this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); - }, - assertVisible: function(element) { - this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); - }, - benchmark: function(operation, iterations) { - var startAt = new Date(); - (iterations || 1).times(operation); - var timeTaken = ((new Date())-startAt); - this.info((arguments[2] || 'Operation') + ' finished ' + - iterations + ' iterations in ' + (timeTaken/1000)+'s' ); - return timeTaken; - } -} - -Test.Unit.Testcase = Class.create(); -Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { - initialize: function(name, test, setup, teardown) { - Test.Unit.Assertions.prototype.initialize.bind(this)(); - this.name = name; - this.test = test || function() {}; - this.setup = setup || function() {}; - this.teardown = teardown || function() {}; - this.isWaiting = false; - this.timeToWait = 1000; - }, - wait: function(time, nextPart) { - this.isWaiting = true; - this.test = nextPart; - this.timeToWait = time; - }, - run: function() { - try { - try { - if (!this.isWaiting) this.setup.bind(this)(); - this.isWaiting = false; - this.test.bind(this)(); - } finally { - if(!this.isWaiting) { - this.teardown.bind(this)(); - } - } - } - catch(e) { this.error(e); } - } -}); diff --git a/vendor/plugins/selenium-on-rails/selenium-core/lib/snapsie.js b/vendor/plugins/selenium-on-rails/selenium-core/lib/snapsie.js deleted file mode 100644 index 23503792..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/lib/snapsie.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * This file wraps the Snapsie ActiveX object, exposing a single saveSnapshot() - * method on a the object. - * - * See http://snapsie.sourceforge.net/ - */ - -function Snapsie() { - // private methods - - function isQuirksMode(inDocument) { - return (inDocument.compatMode == 'BackCompat'); - } - - function getDrawableElement(inDocument) { - if (isQuirksMode(inDocument)) { - var body = inDocument.getElementsByTagName('body')[0]; - return body; - } - else { - // standards mode - return inDocument.documentElement; - } - } - - /** - * Returns the canonical Windows path for a given path. This means - * basically replacing any forwards slashes with backslashes. - * - * @param path the path whose canonical form to return - */ - function getCanonicalPath(path) { - path = path.replace(/\//g, '\\'); - path = path.replace(/\\\\/g, '\\'); - return path; - } - - // public methods - - /** - * Saves a screenshot of the current document to a file. If frameId is - * specified, a screenshot of just the frame is captured instead. - * - * @param outputFile the file to which to save the screenshot - * @param frameId the frame to capture; omit to capture entire document - */ - this.saveSnapshot = function(outputFile, frameId) { - var drawableElement = getDrawableElement(document); - var drawableInfo = { - overflow : drawableElement.style.overflow - , scrollLeft: drawableElement.scrollLeft - , scrollTop : drawableElement.scrollTop - }; - drawableElement.style.overflow = 'hidden'; - - var capturableDocument; - var frameBCR = { left: 0, top: 0 }; - if (!frameId) { - capturableDocument = document; - } - else { - var frame = document.getElementById(frameId); - capturableDocument = frame.document; - - // scroll as much of the frame into view as possible - frameBCR = frame.getBoundingClientRect(); - window.scroll(frameBCR.left, frameBCR.top); - frameBCR = frame.getBoundingClientRect(); - } - - var nativeObj = new ActiveXObject('Snapsie.CoSnapsie'); - nativeObj.saveSnapshot( - getCanonicalPath(outputFile), - frameId, - drawableElement.scrollWidth, - drawableElement.scrollHeight, - drawableElement.clientWidth, - drawableElement.clientHeight, - drawableElement.clientLeft, - drawableElement.clientTop, - frameBCR.left, - frameBCR.top - ); - - // revert - - drawableElement.style.overflow = drawableInfo.overflow; - drawableElement.scrollLeft = drawableInfo.scrollLeft; - drawableElement.scrollTop = drawableInfo.scrollTop; - } -}; diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/find_matching_child.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/find_matching_child.js deleted file mode 100644 index e18a089b..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/find_matching_child.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -elementFindMatchingChildren = function(element, selector) { - var matches = []; - - var childCount = element.childNodes.length; - for (var i=0; i= "1.5"); - if (isRecentFirefox || browserVersion.isKonqueror || browserVersion.isSafari || browserVersion.isOpera) { - text = getTextContent(element); - } else if (element.textContent) { - text = element.textContent; - } else if (element.innerText) { - text = element.innerText; - } - - text = normalizeNewlines(text); - text = normalizeSpaces(text); - - return text.trim(); -} - -function getTextContent(element, preformatted) { - if (element.nodeType == 3 /*Node.TEXT_NODE*/) { - var text = element.data; - if (!preformatted) { - text = text.replace(/\n|\r|\t/g, " "); - } - return text; - } - if (element.nodeType == 1 /*Node.ELEMENT_NODE*/) { - var childrenPreformatted = preformatted || (element.tagName == "PRE"); - var text = ""; - for (var i = 0; i < element.childNodes.length; i++) { - var child = element.childNodes.item(i); - text += getTextContent(child, childrenPreformatted); - } - // Handle block elements that introduce newlines - // -- From HTML spec: - // - // - // TODO: should potentially introduce multiple newlines to separate blocks - if (element.tagName == "P" || element.tagName == "BR" || element.tagName == "HR" || element.tagName == "DIV") { - text += "\n"; - } - return text; - } - return ''; -} - -/** - * Convert all newlines to \n - */ -function normalizeNewlines(text) -{ - return text.replace(/\r\n|\r/g, "\n"); -} - -/** - * Replace multiple sequential spaces with a single space, and then convert   to space. - */ -function normalizeSpaces(text) -{ - // IE has already done this conversion, so doing it again will remove multiple nbsp - if (browserVersion.isIE) - { - return text; - } - - // Replace multiple spaces with a single space - // TODO - this shouldn't occur inside PRE elements - text = text.replace(/\ +/g, " "); - - // Replace   with a space - var nbspPattern = new RegExp(String.fromCharCode(160), "g"); - if (browserVersion.isSafari) { - return replaceAll(text, String.fromCharCode(160), " "); - } else { - return text.replace(nbspPattern, " "); - } -} - -function replaceAll(text, oldText, newText) { - while (text.indexOf(oldText) != -1) { - text = text.replace(oldText, newText); - } - return text; -} - - -function xmlDecode(text) { - text = text.replace(/"/g, '"'); - text = text.replace(/'/g, "'"); - text = text.replace(/</g, "<"); - text = text.replace(/>/g, ">"); - text = text.replace(/&/g, "&"); - return text; -} - -// Sets the text in this element -function setText(element, text) { - if (element.textContent != null) { - element.textContent = text; - } else if (element.innerText != null) { - element.innerText = text; - } -} - -// Get the value of an element -function getInputValue(inputElement) { - if (inputElement.type) { - if (inputElement.type.toUpperCase() == 'CHECKBOX' || - inputElement.type.toUpperCase() == 'RADIO') - { - return (inputElement.checked ? 'on' : 'off'); - } - } - if (inputElement.value == null) { - throw new SeleniumError("This element has no value; is it really a form field?"); - } - return inputElement.value; -} - -/* Fire an event in a browser-compatible manner */ -function triggerEvent(element, eventType, canBubble, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) { - canBubble = (typeof(canBubble) == undefined) ? true : canBubble; - if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) { // IE - var evt = createEventObject(element, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown); - element.fireEvent('on' + eventType, evt); - } - else { - var evt = document.createEvent('HTMLEvents'); - - try { - evt.shiftKey = shiftKeyDown; - evt.metaKey = metaKeyDown; - evt.altKey = altKeyDown; - evt.ctrlKey = controlKeyDown; - } catch (e) { - // On Firefox 1.0, you can only set these during initMouseEvent or initKeyEvent - // we'll have to ignore them here - LOG.exception(e); - } - - evt.initEvent(eventType, canBubble, true); - element.dispatchEvent(evt); - } -} - -function getKeyCodeFromKeySequence(keySequence) { - var match = /^\\(\d{1,3})$/.exec(keySequence); - if (match != null) { - return match[1]; - } - match = /^.$/.exec(keySequence); - if (match != null) { - return match[0].charCodeAt(0); - } - // this is for backward compatibility with existing tests - // 1 digit ascii codes will break however because they are used for the digit chars - match = /^\d{2,3}$/.exec(keySequence); - if (match != null) { - return match[0]; - } - throw new SeleniumError("invalid keySequence"); -} - -function createEventObject(element, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) { - var evt = element.ownerDocument.createEventObject(); - evt.shiftKey = shiftKeyDown; - evt.metaKey = metaKeyDown; - evt.altKey = altKeyDown; - evt.ctrlKey = controlKeyDown; - return evt; -} - -function triggerKeyEvent(element, eventType, keySequence, canBubble, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) { - var keycode = getKeyCodeFromKeySequence(keySequence); - canBubble = (typeof(canBubble) == undefined) ? true : canBubble; - if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) { // IE - var keyEvent = createEventObject(element, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown); - keyEvent.keyCode = keycode; - element.fireEvent('on' + eventType, keyEvent); - } - else { - var evt; - if (window.KeyEvent) { - evt = document.createEvent('KeyEvents'); - evt.initKeyEvent(eventType, true, true, window, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown, keycode, keycode); - } else { - evt = document.createEvent('UIEvents'); - - evt.shiftKey = shiftKeyDown; - evt.metaKey = metaKeyDown; - evt.altKey = altKeyDown; - evt.ctrlKey = controlKeyDown; - - evt.initUIEvent(eventType, true, true, window, 1); - evt.keyCode = keycode; - evt.which = keycode; - } - - element.dispatchEvent(evt); - } -} - -function removeLoadListener(element, command) { - LOG.debug('Removing loadListenter for ' + element + ', ' + command); - if (window.removeEventListener) - element.removeEventListener("load", command, true); - else if (window.detachEvent) - element.detachEvent("onload", command); -} - -function addLoadListener(element, command) { - LOG.debug('Adding loadListenter for ' + element + ', ' + command); - var augmentedCommand = function() { - command.call(this, element); - } - if (window.addEventListener && !browserVersion.isOpera) - element.addEventListener("load", augmentedCommand, true); - else if (window.attachEvent) - element.attachEvent("onload", augmentedCommand); -} - -/** - * Override the broken getFunctionName() method from JsUnit - * This file must be loaded _after_ the jsunitCore.js - */ -function getFunctionName(aFunction) { - var regexpResult = aFunction.toString().match(/function (\w*)/); - if (regexpResult && regexpResult[1]) { - return regexpResult[1]; - } - return 'anonymous'; -} - -function getDocumentBase(doc) { - var bases = document.getElementsByTagName("base"); - if (bases && bases.length && bases[0].href) { - return bases[0].href; - } - return ""; -} - -function getTagName(element) { - var tagName; - if (element && element.tagName && element.tagName.toLowerCase) { - tagName = element.tagName.toLowerCase(); - } - return tagName; -} - -function selArrayToString(a) { - if (isArray(a)) { - // DGF copying the array, because the array-like object may be a non-modifiable nodelist - var retval = []; - for (var i = 0; i < a.length; i++) { - var item = a[i]; - var replaced = new String(item).replace(/([,\\])/g, '\\$1'); - retval[i] = replaced; - } - return retval; - } - return new String(a); -} - - -function isArray(x) { - return ((typeof x) == "object") && (x["length"] != null); -} - -function absolutify(url, baseUrl) { - /** returns a relative url in its absolute form, given by baseUrl. - * - * This function is a little odd, because it can take baseUrls that - * aren't necessarily directories. It uses the same rules as the HTML - * <base> tag; if the baseUrl doesn't end with "/", we'll assume - * that it points to a file, and strip the filename off to find its - * base directory. - * - * So absolutify("foo", "http://x/bar") will return "http://x/foo" (stripping off bar), - * whereas absolutify("foo", "http://x/bar/") will return "http://x/bar/foo" (preserving bar). - * Naturally absolutify("foo", "http://x") will return "http://x/foo", appropriately. - * - * @param url the url to make absolute; if this url is already absolute, we'll just return that, unchanged - * @param baseUrl the baseUrl from which we'll absolutify, following the rules above. - * @return 'url' if it was already absolute, or the absolutized version of url if it was not absolute. - */ - - // DGF isn't there some library we could use for this? - - if (/^\w+:/.test(url)) { - // it's already absolute - return url; - } - - var loc; - try { - loc = parseUrl(baseUrl); - } catch (e) { - // is it an absolute windows file path? let's play the hero in that case - if (/^\w:\\/.test(baseUrl)) { - baseUrl = "file:///" + baseUrl.replace(/\\/g, "/"); - loc = parseUrl(baseUrl); - } else { - throw new SeleniumError("baseUrl wasn't absolute: " + baseUrl); - } - } - loc.search = null; - loc.hash = null; - - // if url begins with /, then that's the whole pathname - if (/^\//.test(url)) { - loc.pathname = url; - var result = reassembleLocation(loc); - return result; - } - - // if pathname is null, then we'll just append "/" + the url - if (!loc.pathname) { - loc.pathname = "/" + url; - var result = reassembleLocation(loc); - return result; - } - - // if pathname ends with /, just append url - if (/\/$/.test(loc.pathname)) { - loc.pathname += url; - var result = reassembleLocation(loc); - return result; - } - - // if we're here, then the baseUrl has a pathname, but it doesn't end with / - // in that case, we replace everything after the final / with the relative url - loc.pathname = loc.pathname.replace(/[^\/\\]+$/, url); - var result = reassembleLocation(loc); - return result; - -} - -var URL_REGEX = /^((\w+):\/\/)(([^:]+):?([^@]+)?@)?([^\/\?:]*):?(\d+)?(\/?[^\?#]+)?\??([^#]+)?#?(.+)?/; - -function parseUrl(url) { - var fields = ['url', null, 'protocol', null, 'username', 'password', 'host', 'port', 'pathname', 'search', 'hash']; - var result = URL_REGEX.exec(url); - if (!result) { - throw new SeleniumError("Invalid URL: " + url); - } - var loc = new Object(); - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - if (field == null) { - continue; - } - loc[field] = result[i]; - } - return loc; -} - -function reassembleLocation(loc) { - if (!loc.protocol) { - throw new Error("Not a valid location object: " + o2s(loc)); - } - var protocol = loc.protocol; - protocol = protocol.replace(/:$/, ""); - var url = protocol + "://"; - if (loc.username) { - url += loc.username; - if (loc.password) { - url += ":" + loc.password; - } - url += "@"; - } - if (loc.host) { - url += loc.host; - } - - if (loc.port) { - url += ":" + loc.port; - } - - if (loc.pathname) { - url += loc.pathname; - } - - if (loc.search) { - url += "?" + loc.search; - } - if (loc.hash) { - var hash = loc.hash; - hash = loc.hash.replace(/^#/, ""); - url += "#" + hash; - } - return url; -} - -function canonicalize(url) { - if(url == "about:blank") - { - return url; - } - var tempLink = window.document.createElement("link"); - tempLink.href = url; // this will canonicalize the href on most browsers - var loc = parseUrl(tempLink.href) - if (!/\/\.\.\//.test(loc.pathname)) { - return tempLink.href; - } - // didn't work... let's try it the hard way - var originalParts = loc.pathname.split("/"); - var newParts = []; - newParts.push(originalParts.shift()); - for (var i = 0; i < originalParts.length; i++) { - var part = originalParts[i]; - if (".." == part) { - newParts.pop(); - continue; - } - newParts.push(part); - } - loc.pathname = newParts.join("/"); - return reassembleLocation(loc); -} - -function extractExceptionMessage(ex) { - if (ex == null) return "null exception"; - if (ex.message != null) return ex.message; - if (ex.toString && ex.toString() != null) return ex.toString(); -} - - -function describe(object, delimiter) { - var props = new Array(); - for (var prop in object) { - try { - props.push(prop + " -> " + object[prop]); - } catch (e) { - props.push(prop + " -> [htmlutils: ack! couldn't read this property! (Permission Denied?)]"); - } - } - return props.join(delimiter || '\n'); -} - -var PatternMatcher = function(pattern) { - this.selectStrategy(pattern); -}; -PatternMatcher.prototype = { - - selectStrategy: function(pattern) { - this.pattern = pattern; - var strategyName = 'glob'; - // by default - if (/^([a-z-]+):(.*)/.test(pattern)) { - var possibleNewStrategyName = RegExp.$1; - var possibleNewPattern = RegExp.$2; - if (PatternMatcher.strategies[possibleNewStrategyName]) { - strategyName = possibleNewStrategyName; - pattern = possibleNewPattern; - } - } - var matchStrategy = PatternMatcher.strategies[strategyName]; - if (!matchStrategy) { - throw new SeleniumError("cannot find PatternMatcher.strategies." + strategyName); - } - this.strategy = matchStrategy; - this.matcher = new matchStrategy(pattern); - }, - - matches: function(actual) { - return this.matcher.matches(actual + ''); - // Note: appending an empty string avoids a Konqueror bug - } - -}; - -/** - * A "static" convenience method for easy matching - */ -PatternMatcher.matches = function(pattern, actual) { - return new PatternMatcher(pattern).matches(actual); -}; - -PatternMatcher.strategies = { - -/** - * Exact matching, e.g. "exact:***" - */ - exact: function(expected) { - this.expected = expected; - this.matches = function(actual) { - return actual == this.expected; - }; - }, - -/** - * Match by regular expression, e.g. "regexp:^[0-9]+$" - */ - regexp: function(regexpString) { - this.regexp = new RegExp(regexpString); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - - regex: function(regexpString) { - this.regexp = new RegExp(regexpString); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - - regexpi: function(regexpString) { - this.regexp = new RegExp(regexpString, "i"); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - - regexi: function(regexpString) { - this.regexp = new RegExp(regexpString, "i"); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - -/** - * "globContains" (aka "wildmat") patterns, e.g. "glob:one,two,*", - * but don't require a perfect match; instead succeed if actual - * contains something that matches globString. - * Making this distinction is motivated by a bug in IE6 which - * leads to the browser hanging if we implement *TextPresent tests - * by just matching against a regular expression beginning and - * ending with ".*". The globcontains strategy allows us to satisfy - * the functional needs of the *TextPresent ops more efficiently - * and so avoid running into this IE6 freeze. - */ - globContains: function(globString) { - this.regexp = new RegExp(PatternMatcher.regexpFromGlobContains(globString)); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - - -/** - * "glob" (aka "wildmat") patterns, e.g. "glob:one,two,*" - */ - glob: function(globString) { - this.regexp = new RegExp(PatternMatcher.regexpFromGlob(globString)); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - } - -}; - -PatternMatcher.convertGlobMetaCharsToRegexpMetaChars = function(glob) { - var re = glob; - re = re.replace(/([.^$+(){}\[\]\\|])/g, "\\$1"); - re = re.replace(/\?/g, "(.|[\r\n])"); - re = re.replace(/\*/g, "(.|[\r\n])*"); - return re; -}; - -PatternMatcher.regexpFromGlobContains = function(globContains) { - return PatternMatcher.convertGlobMetaCharsToRegexpMetaChars(globContains); -}; - -PatternMatcher.regexpFromGlob = function(glob) { - return "^" + PatternMatcher.convertGlobMetaCharsToRegexpMetaChars(glob) + "$"; -}; - -if (!this["Assert"]) Assert = {}; - - -Assert.fail = function(message) { - throw new AssertionFailedError(message); -}; - -/* -* Assert.equals(comment?, expected, actual) -*/ -Assert.equals = function() { - var args = new AssertionArguments(arguments); - if (args.expected === args.actual) { - return; - } - Assert.fail(args.comment + - "Expected '" + args.expected + - "' but was '" + args.actual + "'"); -}; - -Assert.assertEquals = Assert.equals; - -/* -* Assert.matches(comment?, pattern, actual) -*/ -Assert.matches = function() { - var args = new AssertionArguments(arguments); - if (PatternMatcher.matches(args.expected, args.actual)) { - return; - } - Assert.fail(args.comment + - "Actual value '" + args.actual + - "' did not match '" + args.expected + "'"); -} - -/* -* Assert.notMtches(comment?, pattern, actual) -*/ -Assert.notMatches = function() { - var args = new AssertionArguments(arguments); - if (!PatternMatcher.matches(args.expected, args.actual)) { - return; - } - Assert.fail(args.comment + - "Actual value '" + args.actual + - "' did match '" + args.expected + "'"); -} - - -// Preprocess the arguments to allow for an optional comment. -function AssertionArguments(args) { - if (args.length == 2) { - this.comment = ""; - this.expected = args[0]; - this.actual = args[1]; - } else { - this.comment = args[0] + "; "; - this.expected = args[1]; - this.actual = args[2]; - } -} - -function AssertionFailedError(message) { - this.isAssertionFailedError = true; - this.isSeleniumError = true; - this.message = message; - this.failureMessage = message; -} - -function SeleniumError(message) { - var error = new Error(message); - if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA - var result = ''; - for (var a = arguments.caller; a != null; a = a.caller) { - result += '> ' + a.callee.toString() + '\n'; - if (a.caller == a) { - result += '*'; - break; - } - } - error.stack = result; - } - error.isSeleniumError = true; - return error; -} - -function highlight(element) { - var highLightColor = "yellow"; - if (element.originalColor == undefined) { // avoid picking up highlight - element.originalColor = elementGetStyle(element, "background-color"); - } - elementSetStyle(element, {"backgroundColor" : highLightColor}); - window.setTimeout(function() { - try { - //if element is orphan, probably page of it has already gone, so ignore - if (!element.parentNode) { - return; - } - elementSetStyle(element, {"backgroundColor" : element.originalColor}); - } catch (e) {} // DGF unhighlighting is very dangerous and low priority - }, 200); -} - - - -// for use from vs.2003 debugger -function o2s(obj) { - var s = ""; - for (key in obj) { - var line = key + "->" + obj[key]; - line.replace("\n", " "); - s += line + "\n"; - } - return s; -} - -var seenReadyStateWarning = false; - -function openSeparateApplicationWindow(url, suppressMozillaWarning) { - // resize the Selenium window itself - window.resizeTo(1200, 500); - window.moveTo(window.screenX, 0); - - var appWindow = window.open(url + '?start=true', 'main'); - if (appWindow == null) { - var errorMessage = "Couldn't open app window; is the pop-up blocker enabled?" - LOG.error(errorMessage); - throw new Error("Couldn't open app window; is the pop-up blocker enabled?"); - } - try { - var windowHeight = 500; - if (window.outerHeight) { - windowHeight = window.outerHeight; - } else if (document.documentElement && document.documentElement.offsetHeight) { - windowHeight = document.documentElement.offsetHeight; - } - - if (window.screenLeft && !window.screenX) window.screenX = window.screenLeft; - if (window.screenTop && !window.screenY) window.screenY = window.screenTop; - - appWindow.resizeTo(1200, screen.availHeight - windowHeight - 60); - appWindow.moveTo(window.screenX, window.screenY + windowHeight + 25); - } catch (e) { - LOG.error("Couldn't resize app window"); - LOG.exception(e); - } - - - if (!suppressMozillaWarning && window.document.readyState == null && !seenReadyStateWarning) { - alert("Beware! Mozilla bug 300992 means that we can't always reliably detect when a new page has loaded. Install the Selenium IDE extension or the readyState extension available from selenium.openqa.org to make page load detection more reliable."); - seenReadyStateWarning = true; - } - - return appWindow; -} - -var URLConfiguration = classCreate(); -objectExtend(URLConfiguration.prototype, { - initialize: function() { - }, - _isQueryParameterTrue: function (name) { - var parameterValue = this._getQueryParameter(name); - if (parameterValue == null) return false; - if (parameterValue.toLowerCase() == "true") return true; - if (parameterValue.toLowerCase() == "on") return true; - return false; - }, - - _getQueryParameter: function(searchKey) { - var str = this.queryString - if (str == null) return null; - var clauses = str.split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=', 2); - var key = unescape(keyValuePair[0]); - if (key == searchKey) { - return unescape(keyValuePair[1]); - } - } - return null; - }, - - _extractArgs: function() { - var str = SeleniumHTARunner.commandLine; - if (str == null || str == "") return new Array(); - var matches = str.match(/(?:\"([^\"]+)\"|(?!\"([^\"]+)\")(\S+))/g); - // We either want non quote stuff ([^"]+) surrounded by quotes - // or we want to look-ahead, see that the next character isn't - // a quoted argument, and then grab all the non-space stuff - // this will return for the line: "foo" bar - // the results "\"foo\"" and "bar" - - // So, let's unquote the quoted arguments: - var args = new Array; - for (var i = 0; i < matches.length; i++) { - args[i] = matches[i]; - args[i] = args[i].replace(/^"(.*)"$/, "$1"); - } - return args; - }, - - isMultiWindowMode:function() { - return this._isQueryParameterTrue('multiWindow'); - }, - - getBaseUrl:function() { - return this._getQueryParameter('baseUrl'); - - } -}); - - -function safeScrollIntoView(element) { - if (element.scrollIntoView) { - element.scrollIntoView(false); - return; - } - // TODO: work out how to scroll browsers that don't support - // scrollIntoView (like Konqueror) -} - -/** - * Returns the absolute time represented as an offset of the current time. - * Throws a SeleniumException if timeout is invalid. - * - * @param timeout the number of milliseconds from "now" whose absolute time - * to return - */ -function getTimeoutTime(timeout) { - var now = new Date().getTime(); - var timeoutLength = parseInt(timeout); - - if (isNaN(timeoutLength)) { - throw new SeleniumError("Timeout is not a number: '" + timeout + "'"); - } - - return now + timeoutLength; -} - -/** - * Returns true iff the current environment is the IDE. - */ -function is_IDE() -{ - return (typeof(SeleniumIDE) != 'undefined'); -} - -/** - * Logs a message if the Logger exists, and does nothing if it doesn't exist. - * - * @param level the level to log at - * @param msg the message to log - */ -function safe_log(level, msg) -{ - try { - LOG[level](msg); - } - catch (e) { - // couldn't log! - } -} - -/** - * Displays a warning message to the user appropriate to the context under - * which the issue is encountered. This is primarily used to avoid popping up - * alert dialogs that might pause an automated test suite. - * - * @param msg the warning message to display - */ -function safe_alert(msg) -{ - if (is_IDE()) { - alert(msg); - } -} - -/** - * Returns true iff the given element represents a link with a javascript - * href attribute, and does not have an onclick attribute defined. - * - * @param element the element to test - */ -function hasJavascriptHref(element) { - if (getTagName(element) != 'a') { - return false; - } - if (element.onclick) { - return false; - } - if (! element.href) { - return false; - } - if (! /\s*javascript:/i.test(element.href)) { - return false; - } - return true; -} - -/** - * Returns the given element, or its nearest ancestor, that satisfies - * hasJavascriptHref(). Returns null if none is found. - * - * @param element the element whose ancestors to test - */ -function getAncestorOrSelfWithJavascriptHref(element) { - if (hasJavascriptHref(element)) { - return element; - } - if (element.parentNode == null) { - return null; - } - return getAncestorOrSelfWithJavascriptHref(element.parentNode); -} - -//****************************************************************************** -// Locator evaluation support - -/** - * Parses a Selenium locator, returning its type and the unprefixed locator - * string as an object. - * - * @param locator the locator to parse - */ -function parse_locator(locator) -{ - var result = locator.match(/^([A-Za-z]+)=(.+)/); - if (result) { - return { type: result[1].toLowerCase(), string: result[2] }; - } - return { type: 'implicit', string: locator }; -} - -/** - * Evaluates an xpath on a document, and returns a list containing nodes in the - * resulting nodeset. The browserbot xpath methods are now backed by this - * function. A context node may optionally be provided, and the xpath will be - * evaluated from that context. - * - * @param xpath the xpath to evaluate - * @param inDocument the document in which to evaluate the xpath. - * @param opts (optional) An object containing various flags that can - * modify how the xpath is evaluated. Here's a listing of - * the meaningful keys: - * - * contextNode: - * the context node from which to evaluate the xpath. If - * unspecified, the context will be the root document - * element. - * - * namespaceResolver: - * the namespace resolver function. Defaults to null. - * - * xpathLibrary: - * the javascript library to use for XPath. "ajaxslt" is - * the default. "javascript-xpath" is newer and faster, - * but needs more testing. - * - * allowNativeXpath: - * whether to allow native evaluate(). Defaults to true. - * - * ignoreAttributesWithoutValue: - * whether it's ok to ignore attributes without value - * when evaluating the xpath. This can greatly improve - * performance in IE; however, if your xpaths depend on - * such attributes, you can't ignore them! Defaults to - * true. - * - * returnOnFirstMatch: - * whether to optimize the XPath evaluation to only - * return the first match. The match, if any, will still - * be returned in a list. Defaults to false. - */ -function eval_xpath(xpath, inDocument, opts) -{ - if (!opts) { - var opts = {}; - } - var contextNode = opts.contextNode - ? opts.contextNode : inDocument; - var namespaceResolver = opts.namespaceResolver - ? opts.namespaceResolver : null; - var xpathLibrary = opts.xpathLibrary - ? opts.xpathLibrary : null; - var allowNativeXpath = (opts.allowNativeXpath != undefined) - ? opts.allowNativeXpath : true; - var ignoreAttributesWithoutValue = (opts.ignoreAttributesWithoutValue != undefined) - ? opts.ignoreAttributesWithoutValue : true; - var returnOnFirstMatch = (opts.returnOnFirstMatch != undefined) - ? opts.returnOnFirstMatch : false; - - // Trim any trailing "/": not valid xpath, and remains from attribute - // locator. - if (xpath.charAt(xpath.length - 1) == '/') { - xpath = xpath.slice(0, -1); - } - // HUGE hack - remove namespace from xpath for IE - if (browserVersion && browserVersion.isIE) { - xpath = xpath.replace(/x:/g, '') - } - - var nativeXpathAvailable = inDocument.evaluate; - var useNativeXpath = allowNativeXpath && nativeXpathAvailable; - var useDocumentEvaluate = useNativeXpath; - - // When using the new and faster javascript-xpath library, - // we'll use the TestRunner's document object, not the App-Under-Test's document. - // The new library only modifies the TestRunner document with the new - // functionality. - if (xpathLibrary == 'javascript-xpath' && !useNativeXpath) { - documentForXpath = document; - useDocumentEvaluate = true; - } else { - documentForXpath = inDocument; - } - var results = []; - - // this is either native xpath or javascript-xpath via TestRunner.evaluate - if (useDocumentEvaluate) { - try { - // Regarding use of the second argument to document.evaluate(): - // http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/a59ce20639c74ba1/a9d9f53e88e5ebb5 - var xpathResult = documentForXpath - .evaluate((contextNode == inDocument ? xpath : '.' + xpath), - contextNode, namespaceResolver, 0, null); - } - catch (e) { - throw new SeleniumError("Invalid xpath: " + extractExceptionMessage(e)); - } - finally{ - if (xpathResult == null) { - // If the result is null, we should still throw an Error. - throw new SeleniumError("Invalid xpath: " + xpath); - } - } - var result = xpathResult.iterateNext(); - while (result) { - results.push(result); - result = xpathResult.iterateNext(); - } - return results; - } - - // If not, fall back to slower JavaScript implementation - // DGF set xpathdebug = true (using getEval, if you like) to turn on JS XPath debugging - //xpathdebug = true; - var context; - if (contextNode == inDocument) { - context = new ExprContext(inDocument); - } - else { - // provide false values to get the default constructor values - context = new ExprContext(contextNode, false, false, - contextNode.parentNode); - } - context.setCaseInsensitive(true); - context.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue); - context.setReturnOnFirstMatch(returnOnFirstMatch); - var xpathObj; - try { - xpathObj = xpathParse(xpath); - } - catch (e) { - throw new SeleniumError("Invalid xpath: " + extractExceptionMessage(e)); - } - var xpathResult = xpathObj.evaluate(context); - if (xpathResult && xpathResult.value) { - for (var i = 0; i < xpathResult.value.length; ++i) { - results.push(xpathResult.value[i]); - } - } - return results; -} - -/** - * Returns the full resultset of a CSS selector evaluation. - */ -function eval_css(locator, inDocument) -{ - return cssQuery(locator, inDocument); -} - -/** - * This function duplicates part of BrowserBot.findElement() to open up locator - * evaluation on arbitrary documents. It returns a plain old array of located - * elements found by using a Selenium locator. - * - * Multiple results may be generated for xpath and CSS locators. Even though a - * list could potentially be generated for other locator types, such as link, - * we don't try for them, because they aren't very expressive location - * strategies; if you want a list, use xpath or CSS. Furthermore, strategies - * for these locators have been optimized to only return the first result. For - * these types of locators, performance is more important than ideal behavior. - * - * @param locator a locator string - * @param inDocument the document in which to apply the locator - * @param opt_contextNode the context within which to evaluate the locator - * - * @return a list of result elements - */ -function eval_locator(locator, inDocument, opt_contextNode) -{ - locator = parse_locator(locator); - - var pageBot; - if (typeof(selenium) != 'undefined' && selenium != undefined) { - if (typeof(editor) == 'undefined' || editor.state == 'playing') { - safe_log('info', 'Trying [' + locator.type + ']: ' - + locator.string); - } - pageBot = selenium.browserbot; - } - else { - if (!UI_GLOBAL.mozillaBrowserBot) { - // create a browser bot to evaluate the locator. Hand it the IDE - // window as a dummy window, and cache it for future use. - UI_GLOBAL.mozillaBrowserBot = new MozillaBrowserBot(window) - } - pageBot = UI_GLOBAL.mozillaBrowserBot; - } - - var results = []; - - if (locator.type == 'xpath' || (locator.string.charAt(0) == '/' && - locator.type == 'implicit')) { - results = eval_xpath(locator.string, inDocument, - { contextNode: opt_contextNode }); - } - else if (locator.type == 'css') { - results = eval_css(locator.string, inDocument); - } - else { - var element = pageBot - .findElementBy(locator.type, locator.string, inDocument); - if (element != null) { - results.push(element); - } - } - - return results; -} - -//****************************************************************************** -// UI-Element - -/** - * Escapes the special regular expression characters in a string intended to be - * used as a regular expression. - * - * Based on: http://simonwillison.net/2006/Jan/20/escape/ - */ -RegExp.escape = (function() { - var specials = [ - '/', '.', '*', '+', '?', '|', '^', '$', - '(', ')', '[', ']', '{', '}', '\\' - ]; - - var sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - - return function(text) { - return text.replace(sRE, '\\$1'); - } -})(); - -/** - * Returns true if two arrays are identical, and false otherwise. - * - * @param a1 the first array, may only contain simple values (strings or - * numbers) - * @param a2 the second array, same restricts on data as for a1 - * @return true if the arrays are equivalent, false otherwise. - */ -function are_equal(a1, a2) -{ - if (typeof(a1) != typeof(a2)) - return false; - - switch(typeof(a1)) { - case 'object': - // arrays - if (a1.length) { - if (a1.length != a2.length) - return false; - for (var i = 0; i < a1.length; ++i) { - if (!are_equal(a1[i], a2[i])) - return false - } - } - // associative arrays - else { - var keys = {}; - for (var key in a1) { - keys[key] = true; - } - for (var key in a2) { - keys[key] = true; - } - for (var key in keys) { - if (!are_equal(a1[key], a2[key])) - return false; - } - } - return true; - - default: - return a1 == a2; - } -} - - -/** - * Create a clone of an object and return it. This is a deep copy of everything - * but functions, whose references are copied. You shouldn't expect a deep copy - * of functions anyway. - * - * @param orig the original object to copy - * @return a deep copy of the original object. Any functions attached, - * however, will have their references copied only. - */ -function clone(orig) { - var copy; - switch(typeof(orig)) { - case 'object': - copy = (orig.length) ? [] : {}; - for (var attr in orig) { - copy[attr] = clone(orig[attr]); - } - break; - default: - copy = orig; - break; - } - return copy; -} - -/** - * Emulates php's print_r() functionality. Returns a nicely formatted string - * representation of an object. Very useful for debugging. - * - * @param object the object to dump - * @param maxDepth the maximum depth to recurse into the object. Ellipses will - * be shown for objects whose depth exceeds the maximum. - * @param indent the string to use for indenting progressively deeper levels - * of the dump. - * @return a string representing a dump of the object - */ -function print_r(object, maxDepth, indent) -{ - var parentIndent, attr, str = ""; - if (arguments.length == 1) { - var maxDepth = Number.MAX_VALUE; - } else { - maxDepth--; - } - if (arguments.length < 3) { - parentIndent = '' - var indent = ' '; - } else { - parentIndent = indent; - indent += ' '; - } - - switch(typeof(object)) { - case 'object': - if (object.length != undefined) { - if (object.length == 0) { - str += "Array ()\r\n"; - } - else { - str += "Array (\r\n"; - for (var i = 0; i < object.length; ++i) { - str += indent + '[' + i + '] => '; - if (maxDepth == 0) - str += "...\r\n"; - else - str += print_r(object[i], maxDepth, indent); - } - str += parentIndent + ")\r\n"; - } - } - else { - str += "Object (\r\n"; - for (attr in object) { - str += indent + "[" + attr + "] => "; - if (maxDepth == 0) - str += "...\r\n"; - else - str += print_r(object[attr], maxDepth, indent); - } - str += parentIndent + ")\r\n"; - } - break; - case 'boolean': - str += (object ? 'true' : 'false') + "\r\n"; - break; - case 'function': - str += "Function\r\n"; - break; - default: - str += object + "\r\n"; - break; - - } - return str; -} - -/** - * Return an array containing all properties of an object. Perl-style. - * - * @param object the object whose keys to return - * @return array of object keys, as strings - */ -function keys(object) -{ - var keys = []; - for (var k in object) { - keys.push(k); - } - return keys; -} - -/** - * Emulates python's range() built-in. Returns an array of integers, counting - * up (or down) from start to end. Note that the range returned is up to, but - * NOT INCLUDING, end. - *. - * @param start integer from which to start counting. If the end parameter is - * not provided, this value is considered the end and start will - * be zero. - * @param end integer to which to count. If omitted, the function will count - * up from zero to the value of the start parameter. Note that - * the array returned will count up to but will not include this - * value. - * @return an array of consecutive integers. - */ -function range(start, end) -{ - if (arguments.length == 1) { - var end = start; - start = 0; - } - - var r = []; - if (start < end) { - while (start != end) - r.push(start++); - } - else { - while (start != end) - r.push(start--); - } - return r; -} - -/** - * Parses a python-style keyword arguments string and returns the pairs in a - * new object. - * - * @param kwargs a string representing a set of keyword arguments. It should - * look like keyword1=value1, keyword2=value2, ... - * @return an object mapping strings to strings - */ -function parse_kwargs(kwargs) -{ - var args = new Object(); - var pairs = kwargs.split(/,/); - for (var i = 0; i < pairs.length;) { - if (i > 0 && pairs[i].indexOf('=') == -1) { - // the value string contained a comma. Glue the parts back together. - pairs[i-1] += ',' + pairs.splice(i, 1)[0]; - } - else { - ++i; - } - } - for (var i = 0; i < pairs.length; ++i) { - var splits = pairs[i].split(/=/); - if (splits.length == 1) { - continue; - } - var key = splits.shift(); - var value = splits.join('='); - args[key.trim()] = value.trim(); - } - return args; -} - -/** - * Creates a python-style keyword arguments string from an object. - * - * @param args an associative array mapping strings to strings - * @param sortedKeys (optional) a list of keys of the args parameter that - * specifies the order in which the arguments will appear in - * the returned kwargs string - * - * @return a kwarg string representation of args - */ -function to_kwargs(args, sortedKeys) -{ - var s = ''; - if (!sortedKeys) { - var sortedKeys = keys(args).sort(); - } - for (var i = 0; i < sortedKeys.length; ++i) { - var k = sortedKeys[i]; - if (args[k] != undefined) { - if (s) { - s += ', '; - } - s += k + '=' + args[k]; - } - } - return s; -} - -/** - * Returns true if a node is an ancestor node of a target node, and false - * otherwise. - * - * @param node the node being compared to the target node - * @param target the target node - * @return true if node is an ancestor node of target, false otherwise. - */ -function is_ancestor(node, target) -{ - while (target.parentNode) { - target = target.parentNode; - if (node == target) - return true; - } - return false; -} - -//****************************************************************************** -// parseUri 1.2.1 -// MIT License - -/* -Copyright (c) 2007 Steven Levithan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -*/ - -function parseUri (str) { - var o = parseUri.options, - m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; -}; - -parseUri.options = { - strictMode: false, - key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } -}; - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/injection.html b/vendor/plugins/selenium-on-rails/selenium-core/scripts/injection.html deleted file mode 100644 index 546e7500..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/injection.html +++ /dev/null @@ -1,72 +0,0 @@ - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-api.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-api.js deleted file mode 100644 index b55265f8..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-api.js +++ /dev/null @@ -1,3184 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// TODO: stop navigating this.browserbot.document() ... it breaks encapsulation - -var storedVars = new Object(); - -function Selenium(browserbot) { - /** - * Defines an object that runs Selenium commands. - * - *

    Element Locators

    - *

    - * Element Locators tell Selenium which HTML element a command refers to. - * The format of a locator is:

    - *
    - * locatorType=argument - *
    - * - *

    - * We support the following strategies for locating elements: - *

    - * - *
      - *
    • identifier=id: - * Select the element with the specified @id attribute. If no match is - * found, select the first element whose @name attribute is id. - * (This is normally the default; see below.)
    • - *
    • id=id: - * Select the element with the specified @id attribute.
    • - * - *
    • name=name: - * Select the first element with the specified @name attribute. - *
        - *
      • username
      • - *
      • name=username
      • - *
      - * - *

      The name may optionally be followed by one or more element-filters, separated from the name by whitespace. If the filterType is not specified, value is assumed.

      - * - *
        - *
      • name=flavour value=chocolate
      • - *
      - *
    • - *
    • dom=javascriptExpression: - * - * Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object - * Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block. - *
        - *
      • dom=document.forms['myForm'].myDropdown
      • - *
      • dom=document.images[56]
      • - *
      • dom=function foo() { return document.links[1]; }; foo();
      • - *
      - * - *
    • - * - *
    • xpath=xpathExpression: - * Locate an element using an XPath expression. - *
        - *
      • xpath=//img[@alt='The image alt text']
      • - *
      • xpath=//table[@id='table1']//tr[4]/td[2]
      • - *
      • xpath=//a[contains(@href,'#id1')]
      • - *
      • xpath=//a[contains(@href,'#id1')]/@class
      • - *
      • xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
      • - *
      • xpath=//input[@name='name2' and @value='yes']
      • - *
      • xpath=//*[text()="right"]
      • - * - *
      - *
    • - *
    • link=textPattern: - * Select the link (anchor) element which contains text matching the - * specified pattern. - *
        - *
      • link=The link text
      • - *
      - * - *
    • - * - *
    • css=cssSelectorSyntax: - * Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors 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. - *
        - *
      • css=a[href="#id3"]
      • - *
      • css=span#firstChild + span
      • - *
      - *

      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).

      - *
    • - * - *
    • ui=uiSpecifierString: - * Locate an element by resolving the UI specifier string to another locator, and evaluating it. See the Selenium UI-Element Reference for more details. - *
        - *
      • ui=loginPages::loginButton()
      • - *
      • ui=settingsPages::toggle(label=Hide Email)
      • - *
      • ui=forumPages::postBody(index=2)//a[2]
      • - *
      - *
    • - * - *
    - * - *

    - * Without an explicit locator prefix, Selenium uses the following default - * strategies: - *

    - * - *
      - *
    • dom, for locators starting with "document."
    • - *
    • xpath, for locators starting with "//"
    • - *
    • identifier, otherwise
    • - *
    - * - *

    Element Filters

    - *
    - *

    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.

    - *

    Filters look much like locators, ie.

    - *
    - * filterType=argument
    - * - *

    Supported element-filters are:

    - *

    value=valuePattern

    - *
    - * Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.
    - *

    index=index

    - *
    - * Selects a single element based on its position in the list (offset from zero).
    - *
    - * - *

    String-match Patterns

    - * - *

    - * Various Pattern syntaxes are available for matching string values: - *

    - *
      - *
    • glob:pattern: - * Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a - * kind of limited regular-expression syntax typically used in command-line - * shells. In a glob pattern, "*" represents any sequence of characters, and "?" - * represents any single character. Glob patterns match against the entire - * string.
    • - *
    • regexp:regexp: - * Match a string using a regular-expression. The full power of JavaScript - * regular-expressions is available.
    • - *
    • regexpi:regexpi: - * Match a string using a case-insensitive regular-expression.
    • - *
    • exact:string: - * - * Match a string exactly, verbatim, without any of that fancy wildcard - * stuff.
    • - *
    - *

    - * If no pattern prefix is specified, Selenium assumes that it's a "glob" - * pattern. - *

    - *

    - * For commands that return multiple values (such as verifySelectOptions), - * the string being matched is a comma-separated list of the return values, - * where both commas and backslashes in the values are backslash-escaped. - * When providing a pattern, the optional matching syntax (i.e. glob, - * regexp, etc.) is specified once, as usual, at the beginning of the - * pattern. - *

    - */ - this.browserbot = browserbot; - this.optionLocatorFactory = new OptionLocatorFactory(); - // DGF for backwards compatibility - this.page = function() { - return browserbot; - }; - this.defaultTimeout = Selenium.DEFAULT_TIMEOUT; - this.mouseSpeed = 10; -} - -Selenium.DEFAULT_TIMEOUT = 30 * 1000; -Selenium.DEFAULT_MOUSE_SPEED = 10; -Selenium.RIGHT_MOUSE_CLICK = 2; - -Selenium.decorateFunctionWithTimeout = function(f, timeout) { - if (f == null) { - return null; - } - - var timeoutTime = getTimeoutTime(timeout); - - return function() { - if (new Date().getTime() > timeoutTime) { - throw new SeleniumError("Timed out after " + timeout + "ms"); - } - return f(); - }; -} - -Selenium.createForWindow = function(window, proxyInjectionMode) { - if (!window.location) { - throw "error: not a window!"; - } - return new Selenium(BrowserBot.createForWindow(window, proxyInjectionMode)); -}; - -Selenium.prototype.reset = function() { - this.defaultTimeout = Selenium.DEFAULT_TIMEOUT; - // todo: this.browserbot.reset() - this.browserbot.selectWindow("null"); - this.browserbot.resetPopups(); -}; - -Selenium.prototype.doClick = function(locator) { - /** - * Clicks on a link, button, checkbox or radio button. If the click action - * causes a new page to load (like a link usually does), call - * waitForPageToLoad. - * - * @param locator an element locator - * - */ - var element = this.browserbot.findElement(locator); - var elementWithHref = getAncestorOrSelfWithJavascriptHref(element); - - if (browserVersion.isChrome && elementWithHref != null) { - // SEL-621: Firefox chrome: Race condition bug in alert-handling code - // - // This appears to be because javascript href's are being executed in a - // separate thread from the main thread when running in chrome mode. - // - // This workaround injects a callback into the executing href that - // lowers a flag, which is initially raised. Execution of this click - // command will wait for the flag to be lowered. - - var win = elementWithHref.ownerDocument.defaultView; - var originalLocation = win.location.href; - var originalHref = elementWithHref.href; - - elementWithHref.href = 'javascript:try { ' - + originalHref.replace(/^\s*javascript:/i, "") - + '} finally { window._executingJavascriptHref = undefined; }' ; - - win._executingJavascriptHref = true; - - this.browserbot.clickElement(element); - - return Selenium.decorateFunctionWithTimeout(function() { - if (win.closed) { - return true; - } - if (win.location.href != originalLocation) { - // navigated to some other page ... javascript from previous - // page can't still be executing! - return true; - } - if (! win._executingJavascriptHref) { - try { - elementWithHref.href = originalHref; - } - catch (e) { - // maybe the javascript removed the element ... should be - // no danger in not reverting its href attribute - } - return true; - } - - return false; - }, Selenium.DEFAULT_TIMEOUT); - } - - this.browserbot.clickElement(element); -}; - -Selenium.prototype.doDoubleClick = function(locator) { - /** - * Double clicks on a link, button, checkbox or radio button. If the double click action - * causes a new page to load (like a link usually does), call - * waitForPageToLoad. - * - * @param locator an element locator - * - */ - var element = this.browserbot.findElement(locator); - this.browserbot.doubleClickElement(element); -}; - -Selenium.prototype.doContextMenu = function(locator) { - /** - * Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - * - * @param locator an element locator - * - */ - var element = this.browserbot.findElement(locator); - this.browserbot.contextMenuOnElement(element); -}; - -Selenium.prototype.doClickAt = function(locator, coordString) { - /** - * Clicks on a link, button, checkbox or radio button. If the click action - * causes a new page to load (like a link usually does), call - * waitForPageToLoad. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - * - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - this.doMouseMove(locator); - this.doMouseDown(locator); - this.browserbot.clickElement(element, clientXY[0], clientXY[1]); - this.doMouseUp(locator); -}; - -Selenium.prototype.doDoubleClickAt = function(locator, coordString) { - /** - * Doubleclicks on a link, button, checkbox or radio button. If the action - * causes a new page to load (like a link usually does), call - * waitForPageToLoad. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - * - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - this.doMouseMove(locator); - this.doMouseDown(locator); - this.browserbot.doubleClickElement(element, clientXY[0], clientXY[1]); - this.doMouseUp(locator); -}; - -Selenium.prototype.doContextMenuAt = function(locator, coordString) { - /** - * Simulates opening the context menu for the specified element (as might happen if the user "right-clicked" on the element). - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - * - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - this.browserbot.contextMenuOnElement(element, clientXY[0], clientXY[1]); -}; - -Selenium.prototype.doFireEvent = function(locator, eventName) { - /** - * Explicitly simulate an event, to trigger the corresponding "onevent" - * handler. - * - * @param locator an element locator - * @param eventName the event name, e.g. "focus" or "blur" - */ - var element = this.browserbot.findElement(locator); - triggerEvent(element, eventName, false); -}; - -Selenium.prototype.doFocus = function(locator) { - /** Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - if (element.focus) { - element.focus(); - } else { - triggerEvent(element, "focus", false); - } -} - -Selenium.prototype.doKeyPress = function(locator, keySequence) { - /** - * Simulates a user pressing and releasing a key. - * - * @param locator an element locator - * @param keySequence Either be a string("\" followed by the numeric keycode - * of the key to be pressed, normally the ASCII value of that key), or a single - * character. For example: "w", "\119". - */ - var element = this.browserbot.findElement(locator); - triggerKeyEvent(element, 'keypress', keySequence, true, - this.browserbot.controlKeyDown, - this.browserbot.altKeyDown, - this.browserbot.shiftKeyDown, - this.browserbot.metaKeyDown); -}; - -Selenium.prototype.doShiftKeyDown = function() { - /** - * Press the shift key and hold it down until doShiftUp() is called or a new page is loaded. - * - */ - this.browserbot.shiftKeyDown = true; -}; - -Selenium.prototype.doShiftKeyUp = function() { - /** - * Release the shift key. - * - */ - this.browserbot.shiftKeyDown = false; -}; - -Selenium.prototype.doMetaKeyDown = function() { - /** - * Press the meta key and hold it down until doMetaUp() is called or a new page is loaded. - * - */ - this.browserbot.metaKeyDown = true; -}; - -Selenium.prototype.doMetaKeyUp = function() { - /** - * Release the meta key. - * - */ - this.browserbot.metaKeyDown = false; -}; - -Selenium.prototype.doAltKeyDown = function() { - /** - * Press the alt key and hold it down until doAltUp() is called or a new page is loaded. - * - */ - this.browserbot.altKeyDown = true; -}; - -Selenium.prototype.doAltKeyUp = function() { - /** - * Release the alt key. - * - */ - this.browserbot.altKeyDown = false; -}; - -Selenium.prototype.doControlKeyDown = function() { - /** - * Press the control key and hold it down until doControlUp() is called or a new page is loaded. - * - */ - this.browserbot.controlKeyDown = true; -}; - -Selenium.prototype.doControlKeyUp = function() { - /** - * Release the control key. - * - */ - this.browserbot.controlKeyDown = false; -}; - -Selenium.prototype.doKeyDown = function(locator, keySequence) { - /** - * Simulates a user pressing a key (without releasing it yet). - * - * @param locator an element locator - * @param keySequence Either be a string("\" followed by the numeric keycode - * of the key to be pressed, normally the ASCII value of that key), or a single - * character. For example: "w", "\119". - */ - var element = this.browserbot.findElement(locator); - triggerKeyEvent(element, 'keydown', keySequence, true, - this.browserbot.controlKeyDown, - this.browserbot.altKeyDown, - this.browserbot.shiftKeyDown, - this.browserbot.metaKeyDown); -}; - -Selenium.prototype.doKeyUp = function(locator, keySequence) { - /** - * Simulates a user releasing a key. - * - * @param locator an element locator - * @param keySequence Either be a string("\" followed by the numeric keycode - * of the key to be pressed, normally the ASCII value of that key), or a single - * character. For example: "w", "\119". - */ - var element = this.browserbot.findElement(locator); - triggerKeyEvent(element, 'keyup', keySequence, true, - this.browserbot.controlKeyDown, - this.browserbot.altKeyDown, - this.browserbot.shiftKeyDown, - this.browserbot.metaKeyDown); -}; - -function getClientXY(element, coordString) { - // Parse coordString - var coords = null; - var x; - var y; - if (coordString) { - coords = coordString.split(/,/); - x = Number(coords[0]); - y = Number(coords[1]); - } - else { - x = y = 0; - } - - // Get position of element, - // Return 2 item array with clientX and clientY - return [Selenium.prototype.getElementPositionLeft(element) + x, Selenium.prototype.getElementPositionTop(element) + y]; -} - -Selenium.prototype.doMouseOver = function(locator) { - /** - * Simulates a user hovering a mouse over the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mouseover', true); -}; - -Selenium.prototype.doMouseOut = function(locator) { - /** - * Simulates a user moving the mouse pointer away from the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mouseout', true); -}; - -Selenium.prototype.doMouseDown = function(locator) { - /** - * Simulates a user pressing the left mouse button (without releasing it yet) on - * the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mousedown', true); -}; - -Selenium.prototype.doMouseDownRight = function(locator) { - /** - * Simulates a user pressing the right mouse button (without releasing it yet) on - * the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mousedown', true, undefined, undefined, Selenium.RIGHT_MOUSE_CLICK); -}; - -Selenium.prototype.doMouseDownAt = function(locator, coordString) { - /** - * Simulates a user pressing the left mouse button (without releasing it yet) at - * the specified location. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - - this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientXY[0], clientXY[1]); -}; - -Selenium.prototype.doMouseDownRightAt = function(locator, coordString) { - /** - * Simulates a user pressing the right mouse button (without releasing it yet) at - * the specified location. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - - this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientXY[0], clientXY[1], Selenium.RIGHT_MOUSE_CLICK); -}; - -Selenium.prototype.doMouseUp = function(locator) { - /** - * Simulates the event that occurs when the user releases the mouse button (i.e., stops - * holding the button down) on the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mouseup', true); -}; - -Selenium.prototype.doMouseUpRight = function(locator) { - /** - * Simulates the event that occurs when the user releases the right mouse button (i.e., stops - * holding the button down) on the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mouseup', true, undefined, undefined, Selenium.RIGHT_MOUSE_CLICK); -}; - -Selenium.prototype.doMouseUpAt = function(locator, coordString) { - /** - * Simulates the event that occurs when the user releases the mouse button (i.e., stops - * holding the button down) at the specified location. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - - this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientXY[0], clientXY[1]); -}; - -Selenium.prototype.doMouseUpRightAt = function(locator, coordString) { - /** - * Simulates the event that occurs when the user releases the right mouse button (i.e., stops - * holding the button down) at the specified location. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - */ - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - - this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientXY[0], clientXY[1], Selenium.RIGHT_MOUSE_CLICK); -}; - -Selenium.prototype.doMouseMove = function(locator) { - /** - * Simulates a user pressing the mouse button (without releasing it yet) on - * the specified element. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.triggerMouseEvent(element, 'mousemove', true); -}; - -Selenium.prototype.doMouseMoveAt = function(locator, coordString) { - /** - * Simulates a user pressing the mouse button (without releasing it yet) on - * the specified element. - * - * @param locator an element locator - * @param coordString specifies the x,y position (i.e. - 10,20) of the mouse - * event relative to the element returned by the locator. - */ - - var element = this.browserbot.findElement(locator); - var clientXY = getClientXY(element, coordString) - - this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientXY[0], clientXY[1]); -}; - -Selenium.prototype.doType = function(locator, value) { - /** - * Sets the value of an input field, as though you typed it in. - * - *

    Can also be used to set the value of combo boxes, check boxes, etc. In these cases, - * value should be the value of the option selected, not the visible text.

    - * - * @param locator an element locator - * @param value the value to type - */ - if (this.browserbot.controlKeyDown || this.browserbot.altKeyDown || this.browserbot.metaKeyDown) { - throw new SeleniumError("type not supported immediately after call to controlKeyDown() or altKeyDown() or metaKeyDown()"); - } - // TODO fail if it can't be typed into. - var element = this.browserbot.findElement(locator); - if (this.browserbot.shiftKeyDown) { - value = new String(value).toUpperCase(); - } - this.browserbot.replaceText(element, value); -}; - -Selenium.prototype.doTypeKeys = function(locator, value) { - /** - * Simulates keystroke events on the specified element, as though you typed the value key-by-key. - * - *

    This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string; - * this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.

    - * - *

    Unlike the simple "type" command, which forces the specified value into the page directly, this command - * may or may not have any visible effect, even in cases where typing keys would normally have a visible effect. - * For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in - * the field.

    - *

    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 - * send the keystroke events corresponding to what you just typed.

    - * - * @param locator an element locator - * @param value the value to type - */ - var keys = new String(value).split(""); - for (var i = 0; i < keys.length; i++) { - var c = keys[i]; - this.doKeyDown(locator, c); - this.doKeyUp(locator, c); - this.doKeyPress(locator, c); - } -}; - -Selenium.prototype.doSetSpeed = function(value) { - /** - * 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., - * the delay is 0 milliseconds. - * - * @param value the number of milliseconds to pause after operation - */ - throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire"); -}; - -Selenium.prototype.getSpeed = function() { - /** - * 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., - * the delay is 0 milliseconds. - * - * See also setSpeed. - * - * @return string the execution speed in milliseconds. - */ - throw new SeleniumError("this operation is only implemented in selenium-rc, and should never result in a request making it across the wire"); -}; - -Selenium.prototype.findToggleButton = function(locator) { - var element = this.browserbot.findElement(locator); - if (element.checked == null) { - Assert.fail("Element " + locator + " is not a toggle-button."); - } - return element; -} - -Selenium.prototype.doCheck = function(locator) { - /** - * Check a toggle-button (checkbox/radio) - * - * @param locator an element locator - */ - this.findToggleButton(locator).checked = true; -}; - -Selenium.prototype.doUncheck = function(locator) { - /** - * Uncheck a toggle-button (checkbox/radio) - * - * @param locator an element locator - */ - this.findToggleButton(locator).checked = false; -}; - -Selenium.prototype.doSelect = function(selectLocator, optionLocator) { - /** - * Select an option from a drop-down using an option locator. - * - *

    - * Option locators provide different ways of specifying options of an HTML - * Select element (e.g. for selecting a specific option, or for asserting - * that the selected option satisfies a specification). There are several - * forms of Select Option Locator. - *

    - *
      - *
    • label=labelPattern: - * matches options based on their labels, i.e. the visible text. (This - * is the default.) - *
        - *
      • label=regexp:^[Oo]ther
      • - *
      - *
    • - *
    • value=valuePattern: - * matches options based on their values. - *
        - *
      • value=other
      • - *
      - * - * - *
    • - *
    • id=id: - * - * matches options based on their ids. - *
        - *
      • id=option1
      • - *
      - *
    • - *
    • index=index: - * matches an option based on its index (offset from zero). - *
        - * - *
      • index=2
      • - *
      - *
    • - *
    - *

    - * If no option locator prefix is provided, the default behaviour is to match on label. - *

    - * - * - * @param selectLocator an element locator identifying a drop-down menu - * @param optionLocator an option locator (a label by default) - */ - var element = this.browserbot.findElement(selectLocator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - var option = locator.findOption(element); - this.browserbot.selectOption(element, option); -}; - - - -Selenium.prototype.doAddSelection = function(locator, optionLocator) { - /** - * Add a selection to the set of selected options in a multi-select element using an option locator. - * - * @see #doSelect for details of option locators - * - * @param locator an element locator identifying a multi-select box - * @param optionLocator an option locator (a label by default) - */ - var element = this.browserbot.findElement(locator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - var option = locator.findOption(element); - this.browserbot.addSelection(element, option); -}; - -Selenium.prototype.doRemoveSelection = function(locator, optionLocator) { - /** - * Remove a selection from the set of selected options in a multi-select element using an option locator. - * - * @see #doSelect for details of option locators - * - * @param locator an element locator identifying a multi-select box - * @param optionLocator an option locator (a label by default) - */ - - var element = this.browserbot.findElement(locator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - var option = locator.findOption(element); - this.browserbot.removeSelection(element, option); -}; - -Selenium.prototype.doRemoveAllSelections = function(locator) { - /** - * Unselects all of the selected options in a multi-select element. - * - * @param locator an element locator identifying a multi-select box - */ - var element = this.browserbot.findElement(locator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - for (var i = 0; i < element.options.length; i++) { - this.browserbot.removeSelection(element, element.options[i]); - } -} - -Selenium.prototype.doSubmit = function(formLocator) { - /** - * Submit the specified form. This is particularly useful for forms without - * submit buttons, e.g. single-input "Search" forms. - * - * @param formLocator an element locator for the form you want to submit - */ - var form = this.browserbot.findElement(formLocator); - return this.browserbot.submit(form); - -}; - -Selenium.prototype.makePageLoadCondition = function(timeout) { - if (timeout == null) { - timeout = this.defaultTimeout; - } - // if the timeout is zero, we won't wait for the page to load before returning - if (timeout == 0) { - return; - } - return Selenium.decorateFunctionWithTimeout(fnBind(this._isNewPageLoaded, this), timeout); -}; - -Selenium.prototype.doOpen = function(url) { - /** - * Opens an URL in the test frame. This accepts both relative and absolute - * URLs. - * - * The "open" command waits for the page to load before proceeding, - * ie. the "AndWait" suffix is implicit. - * - * Note: The URL must be on the same domain as the runner HTML - * due to security restrictions in the browser (Same Origin Policy). If you - * need to open an URL on another domain, use the Selenium Server to start a - * new browser session on that domain. - * - * @param url the URL to open; may be relative or absolute - */ - this.browserbot.openLocation(url); - if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) { - return this.makePageLoadCondition(); - } // in PI mode, just return "OK"; the server will waitForLoad -}; - -Selenium.prototype.doOpenWindow = function(url, windowID) { - /** - * Opens a popup window (if a window with that ID isn't already open). - * After opening the window, you'll need to select it using the selectWindow - * command. - * - *

    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). - * In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using - * an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - * - * @param url the URL to open, which can be blank - * @param windowID the JavaScript window ID of the window to select - */ - this.browserbot.openWindow(url, windowID); -}; - -Selenium.prototype.doSelectWindow = function(windowID) { - /** - * Selects a popup window using a window locator; once a popup window has been selected, all - * commands go to that window. To select the main window again, use null - * as the target. - * - *

    - * - * Window locators provide different ways of specifying the window object: - * by title, by internal JavaScript "name," or by JavaScript variable. - *

    - *
      - *
    • title=My Special Window: - * Finds the window using the text that appears in the title bar. Be careful; - * two windows can share the same title. If that happens, this locator will - * just pick one. - *
    • - *
    • name=myWindow: - * Finds the window using its internal JavaScript "name" property. This is the second - * parameter "windowName" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag) - * (which Selenium intercepts). - *
    • - *
    • var=variableName: - * Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current - * application window, e.g. "window.foo = window.open(url);". In those cases, you can open the window using - * "var=foo". - *
    • - *
    - *

    - * If no window locator prefix is provided, we'll try to guess what you mean like this:

    - *

    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).

    - *

    2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed - * that this variable contains the return value from a call to the JavaScript window.open() method.

    - *

    3.) Otherwise, selenium looks in a hash it maintains that maps string names to window "names".

    - *

    4.) If that fails, we'll try looping over all of the known windows to try to find the appropriate "title". - * Since "title" is not necessarily unique, this may have unexpected behavior.

    - * - *

    If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages - * which identify the names of windows created via window.open (and therefore intercepted by Selenium). You will see messages - * like the following for each window as it is opened:

    - * - *

    debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"

    - * - *

    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). - * (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 - * an empty (blank) url, like this: openWindow("", "myFunnyWindow").

    - * - * @param windowID the JavaScript window ID of the window to select - */ - this.browserbot.selectWindow(windowID); -}; - -Selenium.prototype.doSelectFrame = function(locator) { - /** - * Selects a frame within the current window. (You may invoke this command - * multiple times to select nested frames.) To select the parent frame, use - * "relative=parent" as a locator; to select the top frame, use "relative=top". - * You can also select a frame by its 0-based index number; select the first frame with - * "index=0", or the third frame with "index=2". - * - *

    You may also use a DOM expression to identify the frame you want directly, - * like this: dom=frames["main"].frames["subframe"]

    - * - * @param locator an element locator identifying a frame or iframe - */ - this.browserbot.selectFrame(locator); -}; - -Selenium.prototype.getWhetherThisFrameMatchFrameExpression = function(currentFrameString, target) { - /** - * Determine whether current/locator identify the frame containing this running code. - * - *

    This is useful in proxy injection mode, where this code runs in every - * browser frame and window, and sometimes the selenium server needs to identify - * the "current" frame. In this case, when the test calls selectFrame, this - * routine is called for each frame to figure out which one has been selected. - * The selected frame will return true, while all others will return false.

    - * - * @param currentFrameString starting frame - * @param target new frame (which might be relative to the current one) - * @return boolean true if the new frame is this code's window - */ - return this.browserbot.doesThisFrameMatchFrameExpression(currentFrameString, target); -}; - -Selenium.prototype.getWhetherThisWindowMatchWindowExpression = function(currentWindowString, target) { - /** - * Determine whether currentWindowString plus target identify the window containing this running code. - * - *

    This is useful in proxy injection mode, where this code runs in every - * browser frame and window, and sometimes the selenium server needs to identify - * the "current" window. In this case, when the test calls selectWindow, this - * routine is called for each window to figure out which one has been selected. - * The selected window will return true, while all others will return false.

    - * - * @param currentWindowString starting window - * @param target new window (which might be relative to the current one, e.g., "_parent") - * @return boolean true if the new window is this code's window - */ - if (window.opener!=null && window.opener[target]!=null && window.opener[target]==window) { - return true; - } - return false; -}; - -Selenium.prototype.doWaitForPopUp = function(windowID, timeout) { - /** - * Waits for a popup window to appear and load up. - * - * @param windowID the JavaScript window "name" of the window that will appear (not the text of the title bar) - * @param timeout a timeout in milliseconds, after which the action will return with an error - */ - var timeoutTime = getTimeoutTime(timeout); - - var popupLoadedPredicate = function () { - var targetWindow; - try { - targetWindow = selenium.browserbot.getWindowByName(windowID, true); - } - catch (e) { - if (new Date().getTime() > timeoutTime) { - throw e; - } - } - - if (!targetWindow) return false; - if (!targetWindow.location) return false; - if ("about:blank" == targetWindow.location) return false; - if (browserVersion.isKonqueror) { - if ("/" == targetWindow.location.href) { - // apparently Konqueror uses this as the temporary location, instead of about:blank - return false; - } - } - if (browserVersion.isSafari) { - if(targetWindow.location.href == selenium.browserbot.buttonWindow.location.href) { - // Apparently Safari uses this as the temporary location, instead of about:blank - // what a world! - LOG.debug("DGF what a world!"); - return false; - } - } - if (!targetWindow.document) return false; - if (!selenium.browserbot.getCurrentWindow().document.readyState) { - // This is Firefox, with no readyState extension - return true; - } - if ('complete' != targetWindow.document.readyState) return false; - return true; - }; - - return Selenium.decorateFunctionWithTimeout(popupLoadedPredicate, timeout); -} - -Selenium.prototype.doWaitForPopUp.dontCheckAlertsAndConfirms = true; - -Selenium.prototype.doChooseCancelOnNextConfirmation = function() { - /** - *

    - * By default, Selenium's overridden window.confirm() function will - * return true, as if the user had manually clicked OK; after running - * this command, the next call to confirm() will return false, as if - * the user had clicked Cancel. Selenium will then resume using the - * default behavior for future confirmations, automatically returning - * true (OK) unless/until you explicitly call this command for each - * confirmation. - *

    - *

    - * Take note - every time a confirmation comes up, you must - * consume it with a corresponding getConfirmation, or else - * the next selenium operation will fail. - *

    - */ - this.browserbot.cancelNextConfirmation(false); -}; - -Selenium.prototype.doChooseOkOnNextConfirmation = function() { - /** - *

    - * Undo the effect of calling chooseCancelOnNextConfirmation. Note - * that Selenium's overridden window.confirm() function will normally automatically - * return true, as if the user had manually clicked OK, so you shouldn't - * need to use this command unless for some reason you need to change - * your mind prior to the next confirmation. After any confirmation, Selenium will resume using the - * default behavior for future confirmations, automatically returning - * true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each - * confirmation. - *

    - *

    - * Take note - every time a confirmation comes up, you must - * consume it with a corresponding getConfirmation, or else - * the next selenium operation will fail. - *

    - * - */ - this.browserbot.cancelNextConfirmation(true); -}; - -Selenium.prototype.doAnswerOnNextPrompt = function(answer) { - /** - * Instructs Selenium to return the specified answer string in response to - * the next JavaScript prompt [window.prompt()]. - * - * - * @param answer the answer to give in response to the prompt pop-up - */ - this.browserbot.setNextPromptResult(answer); -}; - -Selenium.prototype.doGoBack = function() { - /** - * Simulates the user clicking the "back" button on their browser. - * - */ - this.browserbot.goBack(); -}; - -Selenium.prototype.doRefresh = function() { - /** - * Simulates the user clicking the "Refresh" button on their browser. - * - */ - this.browserbot.refresh(); -}; - -Selenium.prototype.doClose = function() { - /** - * Simulates the user clicking the "close" button in the titlebar of a popup - * window or tab. - */ - this.browserbot.close(); -}; - -Selenium.prototype.ensureNoUnhandledPopups = function() { - if (this.browserbot.hasAlerts()) { - throw new SeleniumError("There was an unexpected Alert! [" + this.browserbot.getNextAlert() + "]"); - } - if ( this.browserbot.hasConfirmations() ) { - throw new SeleniumError("There was an unexpected Confirmation! [" + this.browserbot.getNextConfirmation() + "]"); - } -}; - -Selenium.prototype.isAlertPresent = function() { - /** - * Has an alert occurred? - * - *

    - * This function never throws an exception - *

    - * @return boolean true if there is an alert - */ - return this.browserbot.hasAlerts(); -}; - -Selenium.prototype.isPromptPresent = function() { - /** - * Has a prompt occurred? - * - *

    - * This function never throws an exception - *

    - * @return boolean true if there is a pending prompt - */ - return this.browserbot.hasPrompts(); -}; - -Selenium.prototype.isConfirmationPresent = function() { - /** - * Has confirm() been called? - * - *

    - * This function never throws an exception - *

    - * @return boolean true if there is a pending confirmation - */ - return this.browserbot.hasConfirmations(); -}; -Selenium.prototype.getAlert = function() { - /** - * Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts. - * - *

    Getting an alert has the same effect as manually clicking OK. If an - * alert is generated but you do not consume it with getAlert, the next Selenium action - * will fail.

    - * - *

    Under Selenium, JavaScript alerts will NOT pop up a visible alert - * dialog.

    - * - *

    Selenium does NOT support JavaScript alerts that are generated in a - * page's onload() event handler. In this case a visible dialog WILL be - * generated and Selenium will hang until someone manually clicks OK.

    - * @return string The message of the most recent JavaScript alert - - */ - if (!this.browserbot.hasAlerts()) { - Assert.fail("There were no alerts"); - } - return this.browserbot.getNextAlert(); -}; -Selenium.prototype.getAlert.dontCheckAlertsAndConfirms = true; - -Selenium.prototype.getConfirmation = function() { - /** - * Retrieves the message of a JavaScript confirmation dialog generated during - * the previous action. - * - *

    - * By default, the confirm function will return true, having the same effect - * as manually clicking OK. This can be changed by prior execution of the - * chooseCancelOnNextConfirmation command. - *

    - *

    - * If an confirmation is generated but you do not consume it with getConfirmation, - * the next Selenium action will fail. - *

    - * - *

    - * NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible - * dialog. - *

    - * - *

    - * NOTE: Selenium does NOT support JavaScript confirmations that are - * generated in a page's onload() event handler. In this case a visible - * dialog WILL be generated and Selenium will hang until you manually click - * OK. - *

    - * - * @return string the message of the most recent JavaScript confirmation dialog - */ - if (!this.browserbot.hasConfirmations()) { - Assert.fail("There were no confirmations"); - } - return this.browserbot.getNextConfirmation(); -}; -Selenium.prototype.getConfirmation.dontCheckAlertsAndConfirms = true; - -Selenium.prototype.getPrompt = function() { - /** - * Retrieves the message of a JavaScript question prompt dialog generated during - * the previous action. - * - *

    Successful handling of the prompt requires prior execution of the - * answerOnNextPrompt command. If a prompt is generated but you - * do not get/verify it, the next Selenium action will fail.

    - * - *

    NOTE: under Selenium, JavaScript prompts will NOT pop up a visible - * dialog.

    - * - *

    NOTE: Selenium does NOT support JavaScript prompts that are generated in a - * page's onload() event handler. In this case a visible dialog WILL be - * generated and Selenium will hang until someone manually clicks OK.

    - * @return string the message of the most recent JavaScript question prompt - */ - if (! this.browserbot.hasPrompts()) { - Assert.fail("There were no prompts"); - } - return this.browserbot.getNextPrompt(); -}; - -Selenium.prototype.getLocation = function() { - /** Gets the absolute URL of the current page. - * - * @return string the absolute URL of the current page - */ - return this.browserbot.getCurrentWindow().location.href; -}; - -Selenium.prototype.getTitle = function() { - /** Gets the title of the current page. - * - * @return string the title of the current page - */ - return this.browserbot.getTitle(); -}; - - -Selenium.prototype.getBodyText = function() { - /** - * Gets the entire text of the page. - * @return string the entire text of the page - */ - return this.browserbot.bodyText(); -}; - - -Selenium.prototype.getValue = function(locator) { - /** - * Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter). - * For checkbox/radio elements, the value will be "on" or "off" depending on - * whether the element is checked or not. - * - * @param locator an element locator - * @return string the element value, or "on/off" for checkbox/radio elements - */ - var element = this.browserbot.findElement(locator) - return getInputValue(element).trim(); -} - -Selenium.prototype.getText = function(locator) { - /** - * Gets the text of an element. This works for any element that contains - * text. This command uses either the textContent (Mozilla-like browsers) or - * the innerText (IE-like browsers) of the element, which is the rendered - * text shown to the user. - * - * @param locator an element locator - * @return string the text of the element - */ - var element = this.browserbot.findElement(locator); - return getText(element).trim(); -}; - -Selenium.prototype.doHighlight = function(locator) { - /** - * Briefly changes the backgroundColor of the specified element yellow. Useful for debugging. - * - * @param locator an element locator - */ - var element = this.browserbot.findElement(locator); - this.browserbot.highlight(element, true); -}; - -Selenium.prototype.getEval = function(script) { - /** Gets the result of evaluating the specified JavaScript snippet. The snippet may - * have multiple lines, but only the result of the last line will be returned. - * - *

    Note that, by default, the snippet will run in the context of the "selenium" - * object itself, so this will refer to the Selenium object. Use window to - * refer to the window of your application, e.g. window.document.getElementById('foo')

    - * - *

    If you need to use - * a locator to refer to a single element in your application page, you can - * use this.browserbot.findElement("id=foo") where "id=foo" is your locator.

    - * - * @param script the JavaScript snippet to run - * @return string the results of evaluating the snippet - */ - try { - var window = this.browserbot.getCurrentWindow(); - var result = eval(script); - // Selenium RC doesn't allow returning null - if (null == result) return "null"; - return result; - } catch (e) { - throw new SeleniumError("Threw an exception: " + extractExceptionMessage(e)); - } -}; - -Selenium.prototype.isChecked = function(locator) { - /** - * Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button. - * @param locator an element locator pointing to a checkbox or radio button - * @return boolean true if the checkbox is checked, false otherwise - */ - var element = this.browserbot.findElement(locator); - if (element.checked == null) { - throw new SeleniumError("Element " + locator + " is not a toggle-button."); - } - return element.checked; -}; - -Selenium.prototype.getTable = function(tableCellAddress) { - /** - * Gets the text from a cell of a table. The cellAddress syntax - * tableLocator.row.column, where row and column start at 0. - * - * @param tableCellAddress a cell address, e.g. "foo.1.4" - * @return string the text from the specified cell - */ - // This regular expression matches "tableName.row.column" - // For example, "mytable.3.4" - pattern = /(.*)\.(\d+)\.(\d+)/; - - if(!pattern.test(tableCellAddress)) { - throw new SeleniumError("Invalid target format. Correct format is tableName.rowNum.columnNum"); - } - - pieces = tableCellAddress.match(pattern); - - tableName = pieces[1]; - row = pieces[2]; - col = pieces[3]; - - var table = this.browserbot.findElement(tableName); - if (row > table.rows.length) { - Assert.fail("Cannot access row " + row + " - table has " + table.rows.length + " rows"); - } - else if (col > table.rows[row].cells.length) { - Assert.fail("Cannot access column " + col + " - table row has " + table.rows[row].cells.length + " columns"); - } - else { - actualContent = getText(table.rows[row].cells[col]); - return actualContent.trim(); - } - return null; -}; - -Selenium.prototype.getSelectedLabels = function(selectLocator) { - /** Gets all option labels (visible text) for selected options in the specified select or multi-select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string[] an array of all selected option labels in the specified select drop-down - */ - return this.findSelectedOptionProperties(selectLocator, "text"); -} - -Selenium.prototype.getSelectedLabel = function(selectLocator) { - /** Gets option label (visible text) for selected option in the specified select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string the selected option label in the specified select drop-down - */ - return this.findSelectedOptionProperty(selectLocator, "text"); -} - -Selenium.prototype.getSelectedValues = function(selectLocator) { - /** Gets all option values (value attributes) for selected options in the specified select or multi-select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string[] an array of all selected option values in the specified select drop-down - */ - return this.findSelectedOptionProperties(selectLocator, "value"); -} - -Selenium.prototype.getSelectedValue = function(selectLocator) { - /** Gets option value (value attribute) for selected option in the specified select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string the selected option value in the specified select drop-down - */ - return this.findSelectedOptionProperty(selectLocator, "value"); -} - -Selenium.prototype.getSelectedIndexes = function(selectLocator) { - /** Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string[] an array of all selected option indexes in the specified select drop-down - */ - return this.findSelectedOptionProperties(selectLocator, "index"); -} - -Selenium.prototype.getSelectedIndex = function(selectLocator) { - /** Gets option index (option number, starting at 0) for selected option in the specified select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string the selected option index in the specified select drop-down - */ - return this.findSelectedOptionProperty(selectLocator, "index"); -} - -Selenium.prototype.getSelectedIds = function(selectLocator) { - /** Gets all option element IDs for selected options in the specified select or multi-select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string[] an array of all selected option IDs in the specified select drop-down - */ - return this.findSelectedOptionProperties(selectLocator, "id"); -} - -Selenium.prototype.getSelectedId = function(selectLocator) { - /** Gets option element ID for selected option in the specified select element. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string the selected option ID in the specified select drop-down - */ - return this.findSelectedOptionProperty(selectLocator, "id"); -} - -Selenium.prototype.isSomethingSelected = function(selectLocator) { - /** Determines whether some option in a drop-down menu is selected. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return boolean true if some option has been selected, false otherwise - */ - var element = this.browserbot.findElement(selectLocator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - - var selectedOptions = []; - - for (var i = 0; i < element.options.length; i++) { - if (element.options[i].selected) - { - return true; - } - } - return false; -} - -Selenium.prototype.findSelectedOptionProperties = function(locator, property) { - var element = this.browserbot.findElement(locator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - - var selectedOptions = []; - - for (var i = 0; i < element.options.length; i++) { - if (element.options[i].selected) - { - var propVal = element.options[i][property]; - selectedOptions.push(propVal); - } - } - if (selectedOptions.length == 0) Assert.fail("No option selected"); - return selectedOptions; -} - -Selenium.prototype.findSelectedOptionProperty = function(locator, property) { - var selectedOptions = this.findSelectedOptionProperties(locator, property); - if (selectedOptions.length > 1) { - Assert.fail("More than one selected option!"); - } - return selectedOptions[0]; -} - -Selenium.prototype.getSelectOptions = function(selectLocator) { - /** Gets all option labels in the specified select drop-down. - * - * @param selectLocator an element locator identifying a drop-down menu - * @return string[] an array of all option labels in the specified select drop-down - */ - var element = this.browserbot.findElement(selectLocator); - - var selectOptions = []; - - for (var i = 0; i < element.options.length; i++) { - var option = element.options[i].text; - selectOptions.push(option); - } - - return selectOptions; -}; - - -Selenium.prototype.getAttribute = function(attributeLocator) { - /** - * Gets the value of an element attribute. The value of the attribute may - * differ across browsers (this is the case for the "style" attribute, for - * example). - * - * @param attributeLocator an element locator followed by an @ sign and then the name of the attribute, e.g. "foo@bar" - * @return string the value of the specified attribute - */ - var result = this.browserbot.findAttribute(attributeLocator); - if (result == null) { - throw new SeleniumError("Could not find element attribute: " + attributeLocator); - } - return result; -}; - -Selenium.prototype.isTextPresent = function(pattern) { - /** - * Verifies that the specified text pattern appears somewhere on the rendered page shown to the user. - * @param pattern a pattern to match with the text of the page - * @return boolean true if the pattern matches the text, false otherwise - */ - var allText = this.browserbot.bodyText(); - - var patternMatcher = new PatternMatcher(pattern); - if (patternMatcher.strategy == PatternMatcher.strategies.glob) { - if (pattern.indexOf("glob:")==0) { - pattern = pattern.substring("glob:".length); // strip off "glob:" - } - patternMatcher.matcher = new PatternMatcher.strategies.globContains(pattern); - } - else if (patternMatcher.strategy == PatternMatcher.strategies.exact) { - pattern = pattern.substring("exact:".length); // strip off "exact:" - return allText.indexOf(pattern) != -1; - } - return patternMatcher.matches(allText); -}; - -Selenium.prototype.isElementPresent = function(locator) { - /** - * Verifies that the specified element is somewhere on the page. - * @param locator an element locator - * @return boolean true if the element is present, false otherwise - */ - var element = this.browserbot.findElementOrNull(locator); - if (element == null) { - return false; - } - return true; -}; - -Selenium.prototype.isVisible = function(locator) { - /** - * Determines if the specified element is visible. An - * element can be rendered invisible by setting the CSS "visibility" - * property to "hidden", or the "display" property to "none", either for the - * element itself or one if its ancestors. This method will fail if - * the element is not present. - * - * @param locator an element locator - * @return boolean true if the specified element is visible, false otherwise - */ - var element; - element = this.browserbot.findElement(locator); - // DGF if it's an input tag of type "hidden" then it's not visible - if (element.tagName) { - var tagName = new String(element.tagName).toLowerCase(); - if (tagName == "input") { - if (element.type) { - var elementType = new String(element.type).toLowerCase(); - if (elementType == "hidden") { - return false; - } - } - } - } - var visibility = this.findEffectiveStyleProperty(element, "visibility"); - var _isDisplayed = this._isDisplayed(element); - return (visibility != "hidden" && _isDisplayed); -}; - -Selenium.prototype.findEffectiveStyleProperty = function(element, property) { - var effectiveStyle = this.findEffectiveStyle(element); - var propertyValue = effectiveStyle[property]; - if (propertyValue == 'inherit' && element.parentNode.style) { - return this.findEffectiveStyleProperty(element.parentNode, property); - } - return propertyValue; -}; - -Selenium.prototype._isDisplayed = function(element) { - var display = this.findEffectiveStyleProperty(element, "display"); - if (display == "none") return false; - if (element.parentNode.style) { - return this._isDisplayed(element.parentNode); - } - return true; -}; - -Selenium.prototype.findEffectiveStyle = function(element) { - if (element.style == undefined) { - return undefined; // not a styled element - } - var window = this.browserbot.getCurrentWindow(); - if (window.getComputedStyle) { - // DOM-Level-2-CSS - return window.getComputedStyle(element, null); - } - if (element.currentStyle) { - // non-standard IE alternative - return element.currentStyle; - // TODO: this won't really work in a general sense, as - // currentStyle is not identical to getComputedStyle() - // ... but it's good enough for "visibility" - } - - if (window.document.defaultView && window.document.defaultView.getComputedStyle) { - return window.document.defaultView.getComputedStyle(element, null); - } - - - throw new SeleniumError("cannot determine effective stylesheet in this browser"); -}; - -Selenium.prototype.isEditable = function(locator) { - /** - * Determines whether the specified input element is editable, ie hasn't been disabled. - * This method will fail if the specified element isn't an input element. - * - * @param locator an element locator - * @return boolean true if the input element is editable, false otherwise - */ - var element = this.browserbot.findElement(locator); - if (element.value == undefined) { - Assert.fail("Element " + locator + " is not an input."); - } - if (element.disabled) { - return false; - } - // DGF "readonly" is a bit goofy... it doesn't necessarily have a value - // You can write - var readOnlyNode = element.getAttributeNode('readonly'); - if (readOnlyNode) { - // DGF on IE, every input element has a readOnly node, but it may be false - if (typeof(readOnlyNode.nodeValue) == "boolean") { - var readOnly = readOnlyNode.nodeValue; - if (readOnly) { - return false; - } - } else { - return false; - } - } - return true; -}; - -Selenium.prototype.getAllButtons = function() { - /** Returns the IDs of all buttons on the page. - * - *

    If a given button has no ID, it will appear as "" in this array.

    - * - * @return string[] the IDs of all buttons on the page - */ - return this.browserbot.getAllButtons(); -}; - -Selenium.prototype.getAllLinks = function() { - /** Returns the IDs of all links on the page. - * - *

    If a given link has no ID, it will appear as "" in this array.

    - * - * @return string[] the IDs of all links on the page - */ - return this.browserbot.getAllLinks(); -}; - -Selenium.prototype.getAllFields = function() { - /** Returns the IDs of all input fields on the page. - * - *

    If a given field has no ID, it will appear as "" in this array.

    - * - * @return string[] the IDs of all field on the page - */ - return this.browserbot.getAllFields(); -}; - -Selenium.prototype.getAttributeFromAllWindows = function(attributeName) { - /** Returns every instance of some attribute from all known windows. - * - * @param attributeName name of an attribute on the windows - * @return string[] the set of values of this attribute from all known windows. - */ - var attributes = new Array(); - - var win = selenium.browserbot.topWindow; - - // DGF normally you should use []s instead of eval "win."+attributeName - // but in this case, attributeName may contain dots (e.g. document.title) - // in that case, we have no choice but to use eval... - attributes.push(eval("win."+attributeName)); - for (var windowName in this.browserbot.openedWindows) - { - try { - win = selenium.browserbot.openedWindows[windowName]; - attributes.push(eval("win."+attributeName)); - } catch (e) {} // DGF If we miss one... meh. It's probably closed or inaccessible anyway. - } - return attributes; -}; - -Selenium.prototype.findWindow = function(soughtAfterWindowPropertyValue) { - var targetPropertyName = "name"; - if (soughtAfterWindowPropertyValue.match("^title=")) { - targetPropertyName = "document.title"; - soughtAfterWindowPropertyValue = soughtAfterWindowPropertyValue.replace(/^title=/, ""); - } - else { - // matching "name": - // If we are not in proxy injection mode, then the top-level test window will be named selenium_myiframe. - // But as far as the interface goes, we are expected to match a blank string to this window, if - // we are searching with respect to the widow name. - // So make a special case so that this logic will work: - if (PatternMatcher.matches(soughtAfterWindowPropertyValue, "")) { - return this.browserbot.getCurrentWindow(); - } - } - - // DGF normally you should use []s instead of eval "win."+attributeName - // but in this case, attributeName may contain dots (e.g. document.title) - // in that case, we have no choice but to use eval... - if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("this.browserbot.topWindow." + targetPropertyName))) { - return this.browserbot.topWindow; - } - for (windowName in selenium.browserbot.openedWindows) { - var openedWindow = selenium.browserbot.openedWindows[windowName]; - if (PatternMatcher.matches(soughtAfterWindowPropertyValue, eval("openedWindow." + targetPropertyName))) { - return openedWindow; - } - } - throw new SeleniumError("could not find window with property " + targetPropertyName + " matching " + soughtAfterWindowPropertyValue); -}; - -Selenium.prototype.doDragdrop = function(locator, movementsString) { -/** deprecated - use dragAndDrop instead - * - * @param locator an element locator - * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - */ - this.doDragAndDrop(locator, movementsString); -}; - -Selenium.prototype.doSetMouseSpeed = function(pixels) { - /** Configure the number of pixels between "mousemove" events during dragAndDrop commands (default=10). - *

    Setting this value to 0 means that we'll send a "mousemove" event to every single pixel - * in between the start location and the end location; that can be very slow, and may - * cause some browsers to force the JavaScript to timeout.

    - * - *

    If the mouse speed is greater than the distance between the two dragged objects, we'll - * just send one "mousemove" at the start location and then one final one at the end location.

    - * @param pixels the number of pixels between "mousemove" events - */ - this.mouseSpeed = pixels; -} - -Selenium.prototype.getMouseSpeed = function() { - /** Returns the number of pixels between "mousemove" events during dragAndDrop commands (default=10). - * - * @return number the number of pixels between "mousemove" events during dragAndDrop commands (default=10) - */ - this.mouseSpeed = pixels; -} - - -Selenium.prototype.doDragAndDrop = function(locator, movementsString) { - /** Drags an element a certain distance and then drops it - * @param locator an element locator - * @param movementsString offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" - */ - var element = this.browserbot.findElement(locator); - var clientStartXY = getClientXY(element) - var clientStartX = clientStartXY[0]; - var clientStartY = clientStartXY[1]; - - var movements = movementsString.split(/,/); - var movementX = Number(movements[0]); - var movementY = Number(movements[1]); - - var clientFinishX = ((clientStartX + movementX) < 0) ? 0 : (clientStartX + movementX); - var clientFinishY = ((clientStartY + movementY) < 0) ? 0 : (clientStartY + movementY); - - var mouseSpeed = this.mouseSpeed; - var move = function(current, dest) { - if (current == dest) return current; - if (Math.abs(current - dest) < mouseSpeed) return dest; - return (current < dest) ? current + mouseSpeed : current - mouseSpeed; - } - - this.browserbot.triggerMouseEvent(element, 'mousedown', true, clientStartX, clientStartY); - this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientStartX, clientStartY); - var clientX = clientStartX; - var clientY = clientStartY; - - while ((clientX != clientFinishX) || (clientY != clientFinishY)) { - clientX = move(clientX, clientFinishX); - clientY = move(clientY, clientFinishY); - this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientX, clientY); - } - - this.browserbot.triggerMouseEvent(element, 'mousemove', true, clientFinishX, clientFinishY); - this.browserbot.triggerMouseEvent(element, 'mouseup', true, clientFinishX, clientFinishY); -}; - -Selenium.prototype.doDragAndDropToObject = function(locatorOfObjectToBeDragged, locatorOfDragDestinationObject) { -/** Drags an element and drops it on another element - * - * @param locatorOfObjectToBeDragged an element to be dragged - * @param locatorOfDragDestinationObject an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged is dropped - */ - var startX = this.getElementPositionLeft(locatorOfObjectToBeDragged); - var startY = this.getElementPositionTop(locatorOfObjectToBeDragged); - - var destinationLeftX = this.getElementPositionLeft(locatorOfDragDestinationObject); - var destinationTopY = this.getElementPositionTop(locatorOfDragDestinationObject); - var destinationWidth = this.getElementWidth(locatorOfDragDestinationObject); - var destinationHeight = this.getElementHeight(locatorOfDragDestinationObject); - - var endX = Math.round(destinationLeftX + (destinationWidth / 2)); - var endY = Math.round(destinationTopY + (destinationHeight / 2)); - - var deltaX = endX - startX; - var deltaY = endY - startY; - - var movementsString = "" + deltaX + "," + deltaY; - - this.doDragAndDrop(locatorOfObjectToBeDragged, movementsString); -}; - -Selenium.prototype.doWindowFocus = function() { -/** Gives focus to the currently selected window - * - */ - this.browserbot.getCurrentWindow().focus(); -}; - - -Selenium.prototype.doWindowMaximize = function() { -/** Resize currently selected window to take up the entire screen - * - */ - var window = this.browserbot.getCurrentWindow(); - if (window!=null && window.screen) { - window.moveTo(0,0); - window.resizeTo(screen.availWidth, screen.availHeight); - } -}; - -Selenium.prototype.getAllWindowIds = function() { - /** Returns the IDs of all windows that the browser knows about. - * - * @return string[] the IDs of all windows that the browser knows about. - */ - return this.getAttributeFromAllWindows("id"); -}; - -Selenium.prototype.getAllWindowNames = function() { - /** Returns the names of all windows that the browser knows about. - * - * @return string[] the names of all windows that the browser knows about. - */ - return this.getAttributeFromAllWindows("name"); -}; - -Selenium.prototype.getAllWindowTitles = function() { - /** Returns the titles of all windows that the browser knows about. - * - * @return string[] the titles of all windows that the browser knows about. - */ - return this.getAttributeFromAllWindows("document.title"); -}; - -Selenium.prototype.getHtmlSource = function() { - /** Returns the entire HTML source between the opening and - * closing "html" tags. - * - * @return string the entire HTML source - */ - return this.browserbot.getDocument().getElementsByTagName("html")[0].innerHTML; -}; - -Selenium.prototype.doSetCursorPosition = function(locator, position) { - /** - * Moves the text cursor to the specified position in the given input element or textarea. - * This method will fail if the specified element isn't an input element or textarea. - * - * @param locator an element locator pointing to an input element or textarea - * @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. - */ - var element = this.browserbot.findElement(locator); - if (element.value == undefined) { - Assert.fail("Element " + locator + " is not an input."); - } - if (position == -1) { - position = element.value.length; - } - - if( element.setSelectionRange && !browserVersion.isOpera) { - element.focus(); - element.setSelectionRange(/*start*/position,/*end*/position); - } - else if( element.createTextRange ) { - triggerEvent(element, 'focus', false); - var range = element.createTextRange(); - range.collapse(true); - range.moveEnd('character',position); - range.moveStart('character',position); - range.select(); - } -} - -Selenium.prototype.getElementIndex = function(locator) { - /** - * Get the relative index of an element to its parent (starting from 0). The comment node and empty text node - * will be ignored. - * - * @param locator an element locator pointing to an element - * @return number of relative index of the element to its parent (starting from 0) - */ - var element = this.browserbot.findElement(locator); - var previousSibling; - var index = 0; - while ((previousSibling = element.previousSibling) != null) { - if (!this._isCommentOrEmptyTextNode(previousSibling)) { - index++; - } - element = previousSibling; - } - return index; -} - -Selenium.prototype.isOrdered = function(locator1, locator2) { - /** - * Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will - * not be considered ordered. - * - * @param locator1 an element locator pointing to the first element - * @param locator2 an element locator pointing to the second element - * @return boolean true if element1 is the previous sibling of element2, false otherwise - */ - var element1 = this.browserbot.findElement(locator1); - var element2 = this.browserbot.findElement(locator2); - if (element1 === element2) return false; - - var previousSibling; - while ((previousSibling = element2.previousSibling) != null) { - if (previousSibling === element1) { - return true; - } - element2 = previousSibling; - } - return false; -} - -Selenium.prototype._isCommentOrEmptyTextNode = function(node) { - return node.nodeType == 8 || ((node.nodeType == 3) && !(/[^\t\n\r ]/.test(node.data))); -} - -Selenium.prototype.getElementPositionLeft = function(locator) { - /** - * Retrieves the horizontal position of an element - * - * @param locator an element locator pointing to an element OR an element itself - * @return number of pixels from the edge of the frame. - */ - var element; - if ("string"==typeof locator) { - element = this.browserbot.findElement(locator); - } - else { - element = locator; - } - var x = element.offsetLeft; - var elementParent = element.offsetParent; - - while (elementParent != null) - { - if(document.all) - { - if( (elementParent.tagName != "TABLE") && (elementParent.tagName != "BODY") ) - { - x += elementParent.clientLeft; - } - } - else // Netscape/DOM - { - if(elementParent.tagName == "TABLE") - { - var parentBorder = parseInt(elementParent.border); - if(isNaN(parentBorder)) - { - var parentFrame = elementParent.getAttribute('frame'); - if(parentFrame != null) - { - x += 1; - } - } - else if(parentBorder > 0) - { - x += parentBorder; - } - } - } - x += elementParent.offsetLeft; - elementParent = elementParent.offsetParent; - } - return x; -}; - -Selenium.prototype.getElementPositionTop = function(locator) { - /** - * Retrieves the vertical position of an element - * - * @param locator an element locator pointing to an element OR an element itself - * @return number of pixels from the edge of the frame. - */ - var element; - if ("string"==typeof locator) { - element = this.browserbot.findElement(locator); - } - else { - element = locator; - } - - var y = 0; - - while (element != null) - { - if(document.all) - { - if( (element.tagName != "TABLE") && (element.tagName != "BODY") ) - { - y += element.clientTop; - } - } - else // Netscape/DOM - { - if(element.tagName == "TABLE") - { - var parentBorder = parseInt(element.border); - if(isNaN(parentBorder)) - { - var parentFrame = element.getAttribute('frame'); - if(parentFrame != null) - { - y += 1; - } - } - else if(parentBorder > 0) - { - y += parentBorder; - } - } - } - y += element.offsetTop; - - // Netscape can get confused in some cases, such that the height of the parent is smaller - // than that of the element (which it shouldn't really be). If this is the case, we need to - // exclude this element, since it will result in too large a 'top' return value. - if (element.offsetParent && element.offsetParent.offsetHeight && element.offsetParent.offsetHeight < element.offsetHeight) - { - // skip the parent that's too small - element = element.offsetParent.offsetParent; - } - else - { - // Next up... - element = element.offsetParent; - } - } - return y; -}; - -Selenium.prototype.getElementWidth = function(locator) { - /** - * Retrieves the width of an element - * - * @param locator an element locator pointing to an element - * @return number width of an element in pixels - */ - var element = this.browserbot.findElement(locator); - return element.offsetWidth; -}; - -Selenium.prototype.getElementHeight = function(locator) { - /** - * Retrieves the height of an element - * - * @param locator an element locator pointing to an element - * @return number height of an element in pixels - */ - var element = this.browserbot.findElement(locator); - return element.offsetHeight; -}; - -Selenium.prototype.getCursorPosition = function(locator) { - /** - * Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers. - * - *

    Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to - * return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as SEL-243.

    - * This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element. - * - * @param locator an element locator pointing to an input element or textarea - * @return number the numerical position of the cursor in the field - */ - var element = this.browserbot.findElement(locator); - var doc = this.browserbot.getDocument(); - var win = this.browserbot.getCurrentWindow(); - if( doc.selection && !browserVersion.isOpera){ - try { - var selectRange = doc.selection.createRange().duplicate(); - var elementRange = element.createTextRange(); - selectRange.move("character",0); - elementRange.move("character",0); - var inRange1 = selectRange.inRange(elementRange); - var inRange2 = elementRange.inRange(selectRange); - elementRange.setEndPoint("EndToEnd", selectRange); - } catch (e) { - Assert.fail("There is no cursor on this page!"); - } - var answer = String(elementRange.text).replace(/\r/g,"").length; - return answer; - } else { - if (typeof(element.selectionStart) != "undefined") { - if (win.getSelection && typeof(win.getSelection().rangeCount) != undefined && win.getSelection().rangeCount == 0) { - Assert.fail("There is no cursor on this page!"); - } - return element.selectionStart; - } - } - throw new Error("Couldn't detect cursor position on this browser!"); -} - - -Selenium.prototype.getExpression = function(expression) { - /** - * Returns the specified expression. - * - *

    This is useful because of JavaScript preprocessing. - * It is used to generate commands like assertExpression and waitForExpression.

    - * - * @param expression the value to return - * @return string the value passed in - */ - return expression; -} - -Selenium.prototype.getXpathCount = function(xpath) { - /** - * Returns the number of nodes that match the specified xpath, eg. "//table" would give - * the number of tables. - * - * @param xpath the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you. - * @return number the number of nodes that match the specified xpath - */ - var result = this.browserbot.evaluateXPathCount(xpath, this.browserbot.getDocument()); - return result; -} - -Selenium.prototype.doAssignId = function(locator, identifier) { - /** - * Temporarily sets the "id" attribute of the specified element, so you can locate it in the future - * using its ID rather than a slow/complicated XPath. This ID will disappear once the page is - * reloaded. - * @param locator an element locator pointing to an element - * @param identifier a string to be used as the ID of the specified element - */ - var element = this.browserbot.findElement(locator); - element.id = identifier; -} - -Selenium.prototype.doAllowNativeXpath = function(allow) { - /** - * Specifies whether Selenium should use the native in-browser implementation - * of XPath (if any native version is available); if you pass "false" to - * this function, we will always use our pure-JavaScript xpath library. - * Using the pure-JS xpath library can improve the consistency of xpath - * element locators between different browser vendors, but the pure-JS - * version is much slower than the native implementations. - * @param allow boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath - */ - if ("false" == allow || "0" == allow) { // The strings "false" and "0" are true values in JS - allow = false; - } - this.browserbot.allowNativeXpath = allow; -} - -Selenium.prototype.doIgnoreAttributesWithoutValue = function(ignore) { - /** - * Specifies whether Selenium will ignore xpath attributes that have no - * value, i.e. are the empty string, when using the non-native xpath - * evaluation engine. You'd want to do this for performance reasons in IE. - * However, this could break certain xpaths, for example an xpath that looks - * for an attribute whose value is NOT the empty string. - * - * The hope is that such xpaths are relatively rare, but the user should - * have the option of using them. Note that this only influences xpath - * evaluation when using the ajaxslt engine (i.e. not "javascript-xpath"). - * - * @param ignore boolean, true means we'll ignore attributes without value - * at the expense of xpath "correctness"; false means - * we'll sacrifice speed for correctness. - */ - if ('false' == ignore || '0' == ignore) { - ignore = false; - } - this.browserbot.ignoreAttributesWithoutValue = ignore; -} - -Selenium.prototype.doWaitForCondition = function(script, timeout) { - /** - * Runs the specified JavaScript snippet repeatedly until it evaluates to "true". - * The snippet may have multiple lines, but only the result of the last line - * will be considered. - * - *

    Note that, by default, the snippet will be run in the runner's test window, not in the window - * of your application. To get the window of your application, you can use - * the JavaScript snippet selenium.browserbot.getCurrentWindow(), and then - * run your JavaScript in there

    - * @param script the JavaScript snippet to run - * @param timeout a timeout in milliseconds, after which this command will return with an error - */ - - return Selenium.decorateFunctionWithTimeout(function () { - var window = selenium.browserbot.getCurrentWindow(); - return eval(script); - }, timeout); -}; - -Selenium.prototype.doWaitForCondition.dontCheckAlertsAndConfirms = true; - -Selenium.prototype.doSetTimeout = function(timeout) { - /** - * Specifies the amount of time that Selenium will wait for actions to complete. - * - *

    Actions that require waiting include "open" and the "waitFor*" actions.

    - * The default timeout is 30 seconds. - * @param timeout a timeout in milliseconds, after which the action will return with an error - */ - if (!timeout) { - timeout = Selenium.DEFAULT_TIMEOUT; - } - this.defaultTimeout = timeout; -} - -Selenium.prototype.doWaitForPageToLoad = function(timeout) { - /** - * Waits for a new page to load. - * - *

    You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc. - * (which are only available in the JS API).

    - * - *

    Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded" - * flag when it first notices a page load. Running any other Selenium command after - * turns the flag to false. Hence, if you want to wait for a page to load, you must - * wait immediately after a Selenium command that caused a page-load.

    - * @param timeout a timeout in milliseconds, after which this command will return with an error - */ - // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded - if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) { - return this.makePageLoadCondition(timeout); - } -}; - -Selenium.prototype.doWaitForFrameToLoad = function(frameAddress, timeout) { - /** - * Waits for a new frame to load. - * - *

    Selenium constantly keeps track of new pages and frames loading, - * and sets a "newPageLoaded" flag when it first notices a page load.

    - * - * See waitForPageToLoad for more information. - * - * @param frameAddress FrameAddress from the server side - * @param timeout a timeout in milliseconds, after which this command will return with an error - */ - // in pi-mode, the test and the harness share the window; thus if we are executing this code, then we have loaded - if (window["proxyInjectionMode"] == null || !window["proxyInjectionMode"]) { - return this.makePageLoadCondition(timeout); - } -}; - -Selenium.prototype._isNewPageLoaded = function() { - return this.browserbot.isNewPageLoaded(); -}; - -Selenium.prototype.doWaitForPageToLoad.dontCheckAlertsAndConfirms = true; - -/** - * Evaluate a parameter, performing JavaScript evaluation and variable substitution. - * If the string matches the pattern "javascript{ ... }", evaluate the string between the braces. - */ -Selenium.prototype.preprocessParameter = function(value) { - var match = value.match(/^javascript\{((.|\r?\n)+)\}$/); - if (match && match[1]) { - return eval(match[1]).toString(); - } - return this.replaceVariables(value); -}; - -/* - * Search through str and replace all variable references ${varName} with their - * value in storedVars. - */ -Selenium.prototype.replaceVariables = function(str) { - var stringResult = str; - - // Find all of the matching variable references - var match = stringResult.match(/\$\{\w+\}/g); - if (!match) { - return stringResult; - } - - // For each match, lookup the variable value, and replace if found - for (var i = 0; match && i < match.length; i++) { - var variable = match[i]; // The replacement variable, with ${} - var name = variable.substring(2, variable.length - 1); // The replacement variable without ${} - var replacement = storedVars[name]; - if (replacement != undefined) { - stringResult = stringResult.replace(variable, replacement); - } - } - return stringResult; -}; - -Selenium.prototype.getCookie = function() { - /** - * Return all cookies of the current page under test. - * - * @return string all cookies of the current page under test - */ - var doc = this.browserbot.getDocument(); - return doc.cookie; -}; - -Selenium.prototype.getCookieByName = function(name) { - /** - * Returns the value of the cookie with the specified name, or throws an error if the cookie is not present. - * @param name the name of the cookie - * @return string the value of the cookie - */ - var v = this.browserbot.getCookieByName(name); - if (v === null) { - throw new SeleniumError("Cookie '"+name+"' was not found"); - } - return v; -}; - -Selenium.prototype.isCookiePresent = function(name) { - /** - * Returns true if a cookie with the specified name is present, or false otherwise. - * @param name the name of the cookie - * @return boolean true if a cookie with the specified name is present, or false otherwise. - */ - var v = this.browserbot.getCookieByName(name); - var absent = (v === null); - return !absent; -} - -Selenium.prototype.doCreateCookie = function(nameValuePair, optionsString) { - /** - * Create a new cookie whose path and domain are same with those of current page - * under test, unless you specified a path for this cookie explicitly. - * - * @param nameValuePair name and value of the cookie in a format "name=value" - * @param optionsString options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'. - * the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit - * of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will - * usually fail. - */ - var results = /[^\s=\[\]\(\),"\/\?@:;]+=[^\s=\[\]\(\),"\/\?@:;]*/.test(nameValuePair); - if (!results) { - throw new SeleniumError("Invalid parameter."); - } - var cookie = nameValuePair.trim(); - results = /max_age=(\d+)/.exec(optionsString); - if (results) { - var expireDateInMilliseconds = (new Date()).getTime() + results[1] * 1000; - cookie += "; expires=" + new Date(expireDateInMilliseconds).toGMTString(); - } - results = /path=([^\s,]+)[,]?/.exec(optionsString); - if (results) { - var path = results[1]; - if (browserVersion.khtml) { - // Safari and conquerer don't like paths with / at the end - if ("/" != path) { - path = path.replace(/\/$/, ""); - } - } - cookie += "; path=" + path; - } - results = /domain=([^\s,]+)[,]?/.exec(optionsString); - if (results) { - var domain = results[1]; - cookie += "; domain=" + domain; - } - LOG.debug("Setting cookie to: " + cookie); - this.browserbot.getDocument().cookie = cookie; -} - -Selenium.prototype.doDeleteCookie = function(name,optionsString) { - /** - * Delete a named cookie with specified path and domain. Be careful; to delete a cookie, you - * need to delete it using the exact same path and domain that were used to create the cookie. - * If the path is wrong, or the domain is wrong, the cookie simply won't be deleted. Also - * note that specifying a domain that isn't a subset of the current domain will usually fail. - * - * Since there's no way to discover at runtime the original path and domain of a given cookie, - * we've added an option called 'recurse' to try all sub-domains of the current domain with - * all paths that are a subset of the current path. Beware; this option can be slow. In - * big-O notation, it operates in O(n*m) time, where n is the number of dots in the domain - * name and m is the number of slashes in the path. - * - * @param name the name of the cookie to be deleted - * @param optionsString options for the cookie. Currently supported options include 'path', 'domain' - * and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". - * The order of options are irrelevant. Note that specifying a domain that isn't a subset of - * the current domain will usually fail. - */ - // set the expire time of the cookie to be deleted to one minute before now. - var path = ""; - var domain = ""; - var recurse = false; - var matched = false; - results = /path=([^\s,]+)[,]?/.exec(optionsString); - if (results) { - matched = true; - path = results[1]; - } - results = /domain=([^\s,]+)[,]?/.exec(optionsString); - if (results) { - matched = true; - domain = results[1]; - } - results = /recurse=([^\s,]+)[,]?/.exec(optionsString); - if (results) { - matched = true; - recurse = results[1]; - if ("false" == recurse) { - recurse = false; - } - } - // Treat the entire optionsString as a path (for backwards compatibility) - if (optionsString && !matched) { - LOG.warn("Using entire optionsString as a path; please change the argument to deleteCookie to use path="+optionsString); - path = optionsString; - } - if (browserVersion.khtml) { - // Safari and conquerer don't like paths with / at the end - if ("/" != path) { - path = path.replace(/\/$/, ""); - } - } - path = path.trim(); - domain = domain.trim(); - var cookieName = name.trim(); - if (recurse) { - this.browserbot.recursivelyDeleteCookie(cookieName, domain, path); - } else { - this.browserbot.deleteCookie(cookieName, domain, path); - } -} - -Selenium.prototype.doDeleteAllVisibleCookies = function() { - /** Calls deleteCookie with recurse=true on all cookies visible to the current page. - * As noted on the documentation for deleteCookie, recurse=true can be much slower - * than simply deleting the cookies using a known domain/path. - */ - var win = this.browserbot.getCurrentWindow(); - var doc = win.document; - var cookieNames = this.browserbot.getAllCookieNames(doc); - var domain = doc.domain; - var path = win.location.pathname; - for (var i = 0; i < cookieNames.length; i++) { - this.browserbot.recursivelyDeleteCookie(cookieNames[i], domain, path, win); - } -} - -Selenium.prototype.doSetBrowserLogLevel = function(logLevel) { - /** - * Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded. - * Valid logLevel strings are: "debug", "info", "warn", "error" or "off". - * To see the browser logs, you need to - * either show the log window in GUI mode, or enable browser-side logging in Selenium RC. - * - * @param logLevel one of the following: "debug", "info", "warn", "error" or "off" - */ - if (logLevel == null || logLevel == "") { - throw new SeleniumError("You must specify a log level"); - } - logLevel = logLevel.toLowerCase(); - if (LOG.logLevels[logLevel] == null) { - throw new SeleniumError("Invalid log level: " + logLevel); - } - LOG.setLogLevelThreshold(logLevel); -} - -Selenium.prototype.doRunScript = function(script) { - /** - * Creates a new "script" tag in the body of the current test window, and - * adds the specified text into the body of the command. Scripts run in - * this way can often be debugged more easily than scripts executed using - * Selenium's "getEval" command. Beware that JS exceptions thrown in these script - * tags aren't managed by Selenium, so you should probably wrap your script - * in try/catch blocks if there is any chance that the script will throw - * an exception. - * @param script the JavaScript snippet to run - */ - var win = this.browserbot.getCurrentWindow(); - var doc = win.document; - var scriptTag = doc.createElement("script"); - scriptTag.type = "text/javascript" - scriptTag.text = script; - doc.body.appendChild(scriptTag); -} - -Selenium.prototype.doAddLocationStrategy = function(strategyName, functionDefinition) { - /** - * Defines a new function for Selenium to locate elements on the page. - * For example, - * if you define the strategy "foo", and someone runs click("foo=blah"), we'll - * run your function, passing you the string "blah", and click on the element - * that your function - * returns, or throw an "Element not found" error if your function returns null. - * - * We'll pass three arguments to your function: - *
      - *
    • locator: the string the user passed in
    • - *
    • inWindow: the currently selected window
    • - *
    • inDocument: the currently selected document
    • - *
    - * The function must return null if the element can't be found. - * - * @param strategyName the name of the strategy to define; this should use only - * letters [a-zA-Z] with no spaces or other punctuation. - * @param functionDefinition a string defining the body of a function in JavaScript. - * For example: return inDocument.getElementById(locator); - */ - if (!/^[a-zA-Z]+$/.test(strategyName)) { - throw new SeleniumError("Invalid strategy name: " + strategyName); - } - var strategyFunction; - try { - strategyFunction = new Function("locator", "inDocument", "inWindow", functionDefinition); - } catch (ex) { - throw new SeleniumError("Error evaluating function definition: " + extractExceptionMessage(ex)); - } - var safeStrategyFunction = function() { - try { - return strategyFunction.apply(this, arguments); - } catch (ex) { - throw new SeleniumError("Error executing strategy function " + strategyName + ": " + extractExceptionMessage(ex)); - } - } - this.browserbot.locationStrategies[strategyName] = safeStrategyFunction; -} - -Selenium.prototype.doCaptureEntirePageScreenshot = function(filename, kwargs) { - /** - * Saves the entire contents of the current window canvas to a PNG file. - * Contrast this with the captureScreenshot command, which captures the - * contents of the OS viewport (i.e. whatever is currently being displayed - * on the monitor), and is implemented in the RC only. Currently this only - * works in Firefox when running in chrome mode, and in IE non-HTA using - * the EXPERIMENTAL "Snapsie" utility. The Firefox implementation is mostly - * borrowed from the Screengrab! Firefox extension. Please see - * http://www.screengrab.org and http://snapsie.sourceforge.net/ for - * details. - * - * @param filename the path to the file to persist the screenshot as. No - * filename extension will be appended by default. - * Directories will not be created if they do not exist, - * and an exception will be thrown, possibly by native - * code. - * @param kwargs a kwargs string that modifies the way the screenshot - * is captured. Example: "background=#CCFFDD" . - * Currently valid options: - *
    - *
    background
    - *
    the background CSS for the HTML document. This - * may be useful to set for capturing screenshots of - * less-than-ideal layouts, for example where absolute - * positioning causes the calculation of the canvas - * dimension to fail and a black background is exposed - * (possibly obscuring black text).
    - *
    - */ - if (! browserVersion.isChrome && - ! (browserVersion.isIE && ! browserVersion.isHTA)) { - throw new SeleniumError('captureEntirePageScreenshot is only ' - + 'implemented for Firefox ("firefox" or "chrome", NOT ' - + '"firefoxproxy") and IE non-HTA ("iexploreproxy", NOT "iexplore" ' - + 'or "iehta"). The current browser isn\'t one of them!'); - } - - // do or do not ... there is no try - - if (browserVersion.isIE) { - // targeting snapsIE >= 0.2 - function getFailureMessage(exceptionMessage) { - var msg = 'Snapsie failed: '; - if (exceptionMessage) { - if (exceptionMessage == - "Automation server can't create object") { - msg += 'Is it installed? Does it have permission to run ' - 'as an add-on? See http://snapsie.sourceforge.net/'; - } - else { - msg += exceptionMessage; - } - } - else { - msg += 'Undocumented error'; - } - return msg; - } - - if (typeof(runOptions) != 'undefined' && - runOptions.isMultiWindowMode() == false) { - // framed mode - try { - new Snapsie().saveSnapshot(filename, 'selenium_myiframe'); - } - catch (e) { - throw new SeleniumError(getFailureMessage(e.message)); - } - } - else { - // multi-window mode - if (!this.snapsieSrc) { - // XXX - cache snapsie, and capture the screenshot as a - // callback. Definitely a hack, because we may be late taking - // the first screenshot, but saves us from polluting other code - // for now. I wish there were an easier way to get at the - // contents of a referenced script! - var snapsieUrl = (this.browserbot.buttonWindow.location.href) - .replace(/(Test|Remote)Runner\.html/, 'lib/snapsie.js'); - var self = this; - new Ajax.Request(snapsieUrl, { - method: 'get' - , onSuccess: function(transport) { - self.snapsieSrc = transport.responseText; - self.doCaptureEntirePageScreenshot(filename, kwargs); - } - }); - return; - } - - // it's going into a string, so escape the backslashes - filename = filename.replace(/\\/g, '\\\\'); - - // this is sort of hackish. We insert a script into the document, - // and remove it before anyone notices. - var doc = selenium.browserbot.getDocument(); - var script = doc.createElement('script'); - var scriptContent = this.snapsieSrc - + 'try {' - + ' new Snapsie().saveSnapshot("' + filename + '");' - + '}' - + 'catch (e) {' - + ' document.getElementById("takeScreenshot").failure =' - + ' e.message;' - + '}'; - script.id = 'takeScreenshot'; - script.language = 'javascript'; - script.text = scriptContent; - doc.body.appendChild(script); - script.parentNode.removeChild(script); - if (script.failure) { - throw new SeleniumError(getFailureMessage(script.failure)); - } - } - return; - } - - var grabber = { - prepareCanvas: function(width, height) { - var styleWidth = width + 'px'; - var styleHeight = height + 'px'; - - var grabCanvas = document.getElementById('screenshot_canvas'); - if (!grabCanvas) { - // create the canvas - var ns = 'http://www.w3.org/1999/xhtml'; - grabCanvas = document.createElementNS(ns, 'html:canvas'); - grabCanvas.id = 'screenshot_canvas'; - grabCanvas.style.display = 'none'; - document.documentElement.appendChild(grabCanvas); - } - - grabCanvas.width = width; - grabCanvas.style.width = styleWidth; - grabCanvas.style.maxWidth = styleWidth; - grabCanvas.height = height; - grabCanvas.style.height = styleHeight; - grabCanvas.style.maxHeight = styleHeight; - - return grabCanvas; - }, - - prepareContext: function(canvas, box) { - var context = canvas.getContext('2d'); - context.clearRect(box.x, box.y, box.width, box.height); - context.save(); - return context; - } - }; - - var SGNsUtils = { - dataUrlToBinaryInputStream: function(dataUrl) { - var nsIoService = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - var channel = nsIoService - .newChannelFromURI(nsIoService.newURI(dataUrl, null, null)); - var binaryInputStream = Components.classes["@mozilla.org/binaryinputstream;1"] - .createInstance(Components.interfaces.nsIBinaryInputStream); - - binaryInputStream.setInputStream(channel.open()); - return binaryInputStream; - }, - - newFileOutputStream: function(nsFile) { - var writeFlag = 0x02; // write only - var createFlag = 0x08; // create - var truncateFlag = 0x20; // truncate - var fileOutputStream = Components.classes["@mozilla.org/network/file-output-stream;1"] - .createInstance(Components.interfaces.nsIFileOutputStream); - - fileOutputStream.init(nsFile, - writeFlag | createFlag | truncateFlag, 0664, null); - return fileOutputStream; - }, - - writeBinaryInputStreamToFileOutputStream: - function(binaryInputStream, fileOutputStream) { - var numBytes = binaryInputStream.available(); - var bytes = binaryInputStream.readBytes(numBytes); - fileOutputStream.write(bytes, numBytes); - } - }; - - // compute dimensions - var window = this.browserbot.getCurrentWindow(); - var doc = window.document.documentElement; - var box = { - x: 0, - y: 0, - width: doc.scrollWidth, - height: doc.scrollHeight - }; - LOG.debug('computed dimensions'); - - var originalBackground = doc.style.background; - - if (kwargs) { - var args = parse_kwargs(kwargs); - if (args.background) { - doc.style.background = args.background; - } - } - - // grab - var format = 'png'; - var canvas = grabber.prepareCanvas(box.width, box.height); - var context = grabber.prepareContext(canvas, box); - context.drawWindow(window, box.x, box.y, box.width, box.height, - 'rgb(0, 0, 0)'); - context.restore(); - var dataUrl = canvas.toDataURL("image/" + format); - LOG.debug('grabbed to canvas'); - - doc.style.background = originalBackground; - - // save to file - var nsFile = Components.classes["@mozilla.org/file/local;1"] - .createInstance(Components.interfaces.nsILocalFile); - try { - nsFile.initWithPath(filename); - } - catch (e) { - if (/NS_ERROR_FILE_UNRECOGNIZED_PATH/.test(e.message)) { - // try using the opposite file separator - if (filename.indexOf('/') != -1) { - filename = filename.replace(/\//g, '\\'); - } - else { - filename = filename.replace(/\\/g, '/'); - } - nsFile.initWithPath(filename); - } - else { - throw e; - } - } - var binaryInputStream = SGNsUtils.dataUrlToBinaryInputStream(dataUrl); - var fileOutputStream = SGNsUtils.newFileOutputStream(nsFile); - SGNsUtils.writeBinaryInputStreamToFileOutputStream(binaryInputStream, - fileOutputStream); - fileOutputStream.close(); - LOG.debug('saved to file'); -}; - -Selenium.prototype.doRollup = function(rollupName, kwargs) { - /** - * Executes a command rollup, which is a series of commands with a unique - * name, and optionally arguments that control the generation of the set of - * commands. If any one of the rolled-up commands fails, the rollup is - * considered to have failed. Rollups may also contain nested rollups. - * - * @param rollupName the name of the rollup command - * @param kwargs keyword arguments string that influences how the - * rollup expands into commands - */ - // we have to temporarily hijack the commandStarted, nextCommand(), - // commandComplete(), and commandError() methods of the TestLoop object. - // When the expanded rollup commands are done executing (or an error has - // occurred), we'll restore them to their original values. - var loop = currentTest || htmlTestRunner.currentTest; - var backupManager = { - backup: function() { - for (var item in this.data) { - this.data[item] = loop[item]; - } - } - , restore: function() { - for (var item in this.data) { - loop[item] = this.data[item]; - } - } - , data: { - requiresCallBack: null - , commandStarted: null - , nextCommand: null - , commandComplete: null - , commandError: null - , pendingRollupCommands: null - , rollupFailed: null - , rollupFailedMessage: null - } - }; - - var rule = RollupManager.getInstance().getRollupRule(rollupName); - var expandedCommands = rule.getExpandedCommands(kwargs); - - // hold your breath ... - try { - backupManager.backup(); - loop.requiresCallBack = false; - loop.commandStarted = function() {}; - loop.nextCommand = function() { - if (this.pendingRollupCommands.length == 0) { - return null; - } - var command = this.pendingRollupCommands.shift(); - return command; - }; - loop.commandComplete = function(result) { - if (result.failed) { - this.rollupFailed = true; - this.rollupFailureMessages.push(result.failureMessage); - } - - if (this.pendingRollupCommands.length == 0) { - result = { - failed: this.rollupFailed - , failureMessage: this.rollupFailureMessages.join('; ') - }; - LOG.info('Rollup execution complete: ' + (result.failed - ? 'failed! (see error messages below)' : 'ok')); - backupManager.restore(); - this.commandComplete(result); - } - }; - loop.commandError = function(errorMessage) { - LOG.info('Rollup execution complete: bombed!'); - backupManager.restore(); - this.commandError(errorMessage); - }; - - loop.pendingRollupCommands = expandedCommands; - loop.rollupFailed = false; - loop.rollupFailureMessages = []; - } - catch (e) { - LOG.error('Rollup error: ' + e); - backupManager.restore(); - } -}; - -Selenium.prototype.doAddScript = function(scriptContent, scriptTagId) { - /** - * Loads script content into a new script tag in the Selenium document. This - * differs from the runScript command in that runScript adds the script tag - * to the document of the AUT, not the Selenium document. The following - * entities in the script content are replaced by the characters they - * represent: - * - * < - * > - * & - * - * The corresponding remove command is removeScript. - * - * @param scriptContent the Javascript content of the script to add - * @param scriptTagId (optional) the id of the new script tag. If - * specified, and an element with this id already - * exists, this operation will fail. - */ - if (scriptTagId && document.getElementById(scriptTagId)) { - var msg = "Element with id '" + scriptTagId + "' already exists!"; - throw new SeleniumError(msg); - } - - var head = document.getElementsByTagName('head')[0]; - var script = document.createElement('script'); - - script.type = 'text/javascript'; - - if (scriptTagId) { - script.id = scriptTagId; - } - - // replace some entities - scriptContent = scriptContent - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/&/g, '&'); - - script.text = scriptContent; - head.appendChild(script); -}; - -Selenium.prototype.doRemoveScript = function(scriptTagId) { - /** - * Removes a script tag from the Selenium document identified by the given - * id. Does nothing if the referenced tag doesn't exist. - * - * @param scriptTagId the id of the script element to remove. - */ - var script = document.getElementById(scriptTagId); - - if (script && getTagName(script) == 'script') { - script.parentNode.removeChild(script); - } -}; - -Selenium.prototype.doUseXpathLibrary = function(libraryName) { - /** - * Allows choice of one of the available libraries. - * @param libraryName name of the desired library - * Only the following three can be chosen: - * ajaxslt - Google's library - * javascript - Cybozu Labs' faster library - * default - The default library. Currently the default library is ajaxslt. - * If libraryName isn't one of these three, then - * no change will be made. - * - */ - - if (libraryName == "default") { - this.browserbot.xpathLibrary = this.browserbot.defaultXpathLibrary; - return; - } - - if ((libraryName != 'ajaxslt') && (libraryName != 'javascript-xpath')) { - return; - } - - this.browserbot.xpathLibrary = libraryName; - -}; - -/** - * Factory for creating "Option Locators". - * An OptionLocator is an object for dealing with Select options (e.g. for - * finding a specified option, or asserting that the selected option of - * Select element matches some condition. - * The type of locator returned by the factory depends on the locator string: - * label= (OptionLocatorByLabel) - * value= (OptionLocatorByValue) - * index= (OptionLocatorByIndex) - * id= (OptionLocatorById) - * (default is OptionLocatorByLabel). - */ -function OptionLocatorFactory() { -} - -OptionLocatorFactory.prototype.fromLocatorString = function(locatorString) { - var locatorType = 'label'; - var locatorValue = locatorString; - // If there is a locator prefix, use the specified strategy - var result = locatorString.match(/^([a-zA-Z]+)=(.*)/); - if (result) { - locatorType = result[1]; - locatorValue = result[2]; - } - if (this.optionLocators == undefined) { - this.registerOptionLocators(); - } - if (this.optionLocators[locatorType]) { - return new this.optionLocators[locatorType](locatorValue); - } - throw new SeleniumError("Unknown option locator type: " + locatorType); -}; - -/** - * To allow for easy extension, all of the option locators are found by - * searching for all methods of OptionLocatorFactory.prototype that start - * with "OptionLocatorBy". - * TODO: Consider using the term "Option Specifier" instead of "Option Locator". - */ -OptionLocatorFactory.prototype.registerOptionLocators = function() { - this.optionLocators={}; - for (var functionName in this) { - var result = /OptionLocatorBy([A-Z].+)$/.exec(functionName); - if (result != null) { - var locatorName = result[1].lcfirst(); - this.optionLocators[locatorName] = this[functionName]; - } - } -}; - -/** - * OptionLocator for options identified by their labels. - */ -OptionLocatorFactory.prototype.OptionLocatorByLabel = function(label) { - this.label = label; - this.labelMatcher = new PatternMatcher(this.label); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.labelMatcher.matches(element.options[i].text)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with label '" + this.label + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedLabel = element.options[element.selectedIndex].text; - Assert.matches(this.label, selectedLabel) - }; -}; - -/** - * OptionLocator for options identified by their values. - */ -OptionLocatorFactory.prototype.OptionLocatorByValue = function(value) { - this.value = value; - this.valueMatcher = new PatternMatcher(this.value); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.valueMatcher.matches(element.options[i].value)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with value '" + this.value + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedValue = element.options[element.selectedIndex].value; - Assert.matches(this.value, selectedValue) - }; -}; - -/** - * OptionLocator for options identified by their index. - */ -OptionLocatorFactory.prototype.OptionLocatorByIndex = function(index) { - this.index = Number(index); - if (isNaN(this.index) || this.index < 0) { - throw new SeleniumError("Illegal Index: " + index); - } - - this.findOption = function(element) { - if (element.options.length <= this.index) { - throw new SeleniumError("Index out of range. Only " + element.options.length + " options available"); - } - return element.options[this.index]; - }; - - this.assertSelected = function(element) { - Assert.equals(this.index, element.selectedIndex); - }; -}; - -/** - * OptionLocator for options identified by their id. - */ -OptionLocatorFactory.prototype.OptionLocatorById = function(id) { - this.id = id; - this.idMatcher = new PatternMatcher(this.id); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.idMatcher.matches(element.options[i].id)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with id '" + this.id + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedId = element.options[element.selectedIndex].id; - Assert.matches(this.id, selectedId) - }; -}; - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserbot.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserbot.js deleted file mode 100644 index c8a66aca..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserbot.js +++ /dev/null @@ -1,2300 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -/* -* This script provides the Javascript API to drive the test application contained within -* a Browser Window. -* TODO: -* Add support for more events (keyboard and mouse) -* Allow to switch "user-entry" mode from mouse-based to keyboard-based, firing different -* events in different modes. -*/ - -// The window to which the commands will be sent. For example, to click on a -// popup window, first select that window, and then do a normal click command. -var BrowserBot = function(topLevelApplicationWindow) { - this.topWindow = topLevelApplicationWindow; - this.topFrame = this.topWindow; - this.baseUrl=window.location.href; - - // the buttonWindow is the Selenium window - // it contains the Run/Pause buttons... this should *not* be the AUT window - this.buttonWindow = window; - this.currentWindow = this.topWindow; - this.currentWindowName = null; - this.allowNativeXpath = true; - this.xpathLibrary = this.defaultXpathLibrary = 'ajaxslt' // change to "javascript-xpath" for the newer, faster engine - - // We need to know this in advance, in case the frame closes unexpectedly - this.isSubFrameSelected = false; - - this.altKeyDown = false; - this.controlKeyDown = false; - this.shiftKeyDown = false; - this.metaKeyDown = false; - - this.modalDialogTest = null; - this.recordedAlerts = new Array(); - this.recordedConfirmations = new Array(); - this.recordedPrompts = new Array(); - this.openedWindows = {}; - this.nextConfirmResult = true; - this.nextPromptResult = ''; - this.newPageLoaded = false; - this.pageLoadError = null; - - this.shouldHighlightLocatedElement = false; - - this.uniqueId = "seleniumMarker" + new Date().getTime(); - this.pollingForLoad = new Object(); - this.permDeniedCount = new Object(); - this.windowPollers = new Array(); - // DGF for backwards compatibility - this.browserbot = this; - - var self = this; - - objectExtend(this, PageBot.prototype); - this._registerAllLocatorFunctions(); - - this.recordPageLoad = function(elementOrWindow) { - LOG.debug("Page load detected"); - try { - if (elementOrWindow.location && elementOrWindow.location.href) { - LOG.debug("Page load location=" + elementOrWindow.location.href); - } else if (elementOrWindow.contentWindow && elementOrWindow.contentWindow.location && elementOrWindow.contentWindow.location.href) { - LOG.debug("Page load location=" + elementOrWindow.contentWindow.location.href); - } else { - LOG.debug("Page load location unknown, current window location=" + this.getCurrentWindow(true).location); - } - } catch (e) { - LOG.error("Caught an exception attempting to log location; this should get noticed soon!"); - LOG.exception(e); - self.pageLoadError = e; - return; - } - self.newPageLoaded = true; - }; - - this.isNewPageLoaded = function() { - if (this.pageLoadError) { - LOG.error("isNewPageLoaded found an old pageLoadError"); - var e = this.pageLoadError; - this.pageLoadError = null; - throw e; - } - return self.newPageLoaded; - }; - -}; - -// DGF PageBot exists for backwards compatibility with old user-extensions -var PageBot = function(){}; - -BrowserBot.createForWindow = function(window, proxyInjectionMode) { - var browserbot; - LOG.debug('createForWindow'); - LOG.debug("browserName: " + browserVersion.name); - LOG.debug("userAgent: " + navigator.userAgent); - if (browserVersion.isIE) { - browserbot = new IEBrowserBot(window); - } - else if (browserVersion.isKonqueror) { - browserbot = new KonquerorBrowserBot(window); - } - else if (browserVersion.isOpera) { - browserbot = new OperaBrowserBot(window); - } - else if (browserVersion.isSafari) { - browserbot = new SafariBrowserBot(window); - } - else { - // Use mozilla by default - browserbot = new MozillaBrowserBot(window); - } - // getCurrentWindow has the side effect of modifying it to handle page loads etc - browserbot.proxyInjectionMode = proxyInjectionMode; - browserbot.getCurrentWindow(); // for modifyWindow side effect. This is not a transparent style - return browserbot; -}; - -// todo: rename? This doesn't actually "do" anything. -BrowserBot.prototype.doModalDialogTest = function(test) { - this.modalDialogTest = test; -}; - -BrowserBot.prototype.cancelNextConfirmation = function(result) { - this.nextConfirmResult = result; -}; - -BrowserBot.prototype.setNextPromptResult = function(result) { - this.nextPromptResult = result; -}; - -BrowserBot.prototype.hasAlerts = function() { - return (this.recordedAlerts.length > 0); -}; - -BrowserBot.prototype.relayBotToRC = function(s) { - // DGF need to do this funny trick to see if we're in PI mode, because - // "this" might be the window, rather than the browserbot (e.g. during window.alert) - var piMode = this.proxyInjectionMode; - if (!piMode) { - if (typeof(selenium) != "undefined") { - piMode = selenium.browserbot && selenium.browserbot.proxyInjectionMode; - } - } - if (piMode) { - this.relayToRC("selenium." + s); - } -}; - -BrowserBot.prototype.relayToRC = function(name) { - var object = eval(name); - var s = 'state:' + serializeObject(name, object) + "\n"; - sendToRC(s,"state=true"); -} - -BrowserBot.prototype.resetPopups = function() { - this.recordedAlerts = []; - this.recordedConfirmations = []; - this.recordedPrompts = []; -} - -BrowserBot.prototype.getNextAlert = function() { - var t = this.recordedAlerts.shift(); - if (t) { - t = t.replace(/\n/g, " "); // because Selenese loses \n's when retrieving text from HTML table - } - this.relayBotToRC("browserbot.recordedAlerts"); - return t; -}; - -BrowserBot.prototype.hasConfirmations = function() { - return (this.recordedConfirmations.length > 0); -}; - -BrowserBot.prototype.getNextConfirmation = function() { - var t = this.recordedConfirmations.shift(); - this.relayBotToRC("browserbot.recordedConfirmations"); - return t; -}; - -BrowserBot.prototype.hasPrompts = function() { - return (this.recordedPrompts.length > 0); -}; - -BrowserBot.prototype.getNextPrompt = function() { - var t = this.recordedPrompts.shift(); - this.relayBotToRC("browserbot.recordedPrompts"); - return t; -}; - -/* Fire a mouse event in a browser-compatible manner */ - -BrowserBot.prototype.triggerMouseEvent = function(element, eventType, canBubble, clientX, clientY, button) { - clientX = clientX ? clientX : 0; - clientY = clientY ? clientY : 0; - - LOG.debug("triggerMouseEvent assumes setting screenX and screenY to 0 is ok"); - var screenX = 0; - var screenY = 0; - - canBubble = (typeof(canBubble) == undefined) ? true : canBubble; - if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) { //IE - var evt = createEventObject(element, this.controlKeyDown, this.altKeyDown, this.shiftKeyDown, this.metaKeyDown); - evt.detail = 0; - evt.button = button ? button : 1; // default will be the left mouse click ( http://www.javascriptkit.com/jsref/event.shtml ) - evt.relatedTarget = null; - if (!screenX && !screenY && !clientX && !clientY && !this.controlKeyDown && !this.altKeyDown && !this.shiftKeyDown && !this.metaKeyDown) { - element.fireEvent('on' + eventType); - } - else { - evt.screenX = screenX; - evt.screenY = screenY; - evt.clientX = clientX; - evt.clientY = clientY; - - // when we go this route, window.event is never set to contain the event we have just created. - // ideally we could just slide it in as follows in the try-block below, but this normally - // doesn't work. This is why I try to avoid this code path, which is only required if we need to - // set attributes on the event (e.g., clientX). - try { - window.event = evt; - } - catch(e) { - // getting an "Object does not support this action or property" error. Save the event away - // for future reference. - // TODO: is there a way to update window.event? - - // work around for http://jira.openqa.org/browse/SEL-280 -- make the event available somewhere: - selenium.browserbot.getCurrentWindow().selenium_event = evt; - } - element.fireEvent('on' + eventType, evt); - } - } - else { - var evt = document.createEvent('MouseEvents'); - if (evt.initMouseEvent) - { - // see http://developer.mozilla.org/en/docs/DOM:event.button and - // http://developer.mozilla.org/en/docs/DOM:event.initMouseEvent for button ternary logic logic - //Safari - evt.initMouseEvent(eventType, canBubble, true, document.defaultView, 1, screenX, screenY, clientX, clientY, - this.controlKeyDown, this.altKeyDown, this.shiftKeyDown, this.metaKeyDown, button ? button : 0, null); - } - else { - LOG.warn("element doesn't have initMouseEvent; firing an event which should -- but doesn't -- have other mouse-event related attributes here, as well as controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown"); - evt.initEvent(eventType, canBubble, true); - - evt.shiftKey = this.shiftKeyDown; - evt.metaKey = this.metaKeyDown; - evt.altKey = this.altKeyDown; - evt.ctrlKey = this.controlKeyDown; - if(button) - { - evt.button = button; - } - } - element.dispatchEvent(evt); - } -} - -BrowserBot.prototype._windowClosed = function(win) { - var c = win.closed; - if (c == null) return true; - return c; -}; - -BrowserBot.prototype._modifyWindow = function(win) { - // In proxyInjectionMode, have to suppress LOG calls in _modifyWindow to avoid an infinite loop - if (this._windowClosed(win)) { - if (!this.proxyInjectionMode) { - LOG.error("modifyWindow: Window was closed!"); - } - return null; - } - if (!this.proxyInjectionMode) { - LOG.debug('modifyWindow ' + this.uniqueId + ":" + win[this.uniqueId]); - } - if (!win[this.uniqueId]) { - win[this.uniqueId] = 1; - this.modifyWindowToRecordPopUpDialogs(win, this); - } - // In proxyInjection mode, we have our own mechanism for detecting page loads - if (!this.proxyInjectionMode) { - this.modifySeparateTestWindowToDetectPageLoads(win); - } - if (win.frames && win.frames.length && win.frames.length > 0) { - for (var i = 0; i < win.frames.length; i++) { - try { - this._modifyWindow(win.frames[i]); - } catch (e) {} // we're just trying to be opportunistic; don't worry if this doesn't work out - } - } - return win; -}; - -BrowserBot.prototype.selectWindow = function(target) { - if (!target || target == "null") { - this._selectTopWindow(); - return; - } - var result = target.match(/^([a-zA-Z]+)=(.*)/); - if (!result) { - try { - this._selectWindowByName(target); - } - catch (e) { - this._selectWindowByTitle(target); - } - return; - } - locatorType = result[1]; - locatorValue = result[2]; - if (locatorType == "title") { - this._selectWindowByTitle(locatorValue); - } - // TODO separate name and var into separate functions - else if (locatorType == "name") { - this._selectWindowByName(locatorValue); - } else if (locatorType == "var") { - this._selectWindowByName(locatorValue); - } else { - throw new SeleniumError("Window locator not recognized: " + locatorType); - } -}; - -BrowserBot.prototype._selectTopWindow = function() { - this.currentWindowName = null; - this.currentWindow = this.topWindow; - this.topFrame = this.topWindow; - this.isSubFrameSelected = false; -} - -BrowserBot.prototype._selectWindowByName = function(target) { - this.currentWindow = this.getWindowByName(target, false); - this.topFrame = this.currentWindow; - this.currentWindowName = target; - this.isSubFrameSelected = false; -} - -BrowserBot.prototype._selectWindowByTitle = function(target) { - var windowName = this.getWindowNameByTitle(target); - if (!windowName) { - this._selectTopWindow(); - } else { - this._selectWindowByName(windowName); - } -} - -BrowserBot.prototype.selectFrame = function(target) { - if (target.indexOf("index=") == 0) { - target = target.substr(6); - var frame = this.getCurrentWindow().frames[target]; - if (frame == null) { - throw new SeleniumError("Not found: frames["+index+"]"); - } - if (!frame.document) { - throw new SeleniumError("frames["+index+"] is not a frame"); - } - this.currentWindow = frame; - this.isSubFrameSelected = true; - } - else if (target == "relative=up" || target == "relative=parent") { - this.currentWindow = this.getCurrentWindow().parent; - this.isSubFrameSelected = (this._getFrameElement(this.currentWindow) != null); - } else if (target == "relative=top") { - this.currentWindow = this.topFrame; - this.isSubFrameSelected = false; - } else { - var frame = this.findElement(target); - if (frame == null) { - throw new SeleniumError("Not found: " + target); - } - // now, did they give us a frame or a frame ELEMENT? - var match = false; - if (frame.contentWindow) { - // this must be a frame element - if (browserVersion.isHTA) { - // stupid HTA bug; can't get in the front door - target = frame.contentWindow.name; - } else { - this.currentWindow = frame.contentWindow; - this.isSubFrameSelected = true; - match = true; - } - } else if (frame.document && frame.location) { - // must be an actual window frame - this.currentWindow = frame; - this.isSubFrameSelected = true; - match = true; - } - - if (!match) { - // neither, let's loop through the frame names - var win = this.getCurrentWindow(); - - if (win && win.frames && win.frames.length) { - for (var i = 0; i < win.frames.length; i++) { - if (win.frames[i].name == target) { - this.currentWindow = win.frames[i]; - this.isSubFrameSelected = true; - match = true; - break; - } - } - } - if (!match) { - throw new SeleniumError("Not a frame: " + target); - } - } - } - // modifies the window - this.getCurrentWindow(); -}; - -BrowserBot.prototype.doesThisFrameMatchFrameExpression = function(currentFrameString, target) { - var isDom = false; - if (target.indexOf("dom=") == 0) { - target = target.substr(4); - isDom = true; - } else if (target.indexOf("index=") == 0) { - target = "frames[" + target.substr(6) + "]"; - isDom = true; - } - var t; - try { - eval("t=" + currentFrameString + "." + target); - } catch (e) { - } - var autWindow = this.browserbot.getCurrentWindow(); - if (t != null) { - try { - if (t.window == autWindow) { - return true; - } - if (t.window.uniqueId == autWindow.uniqueId) { - return true; - } - return false; - } catch (permDenied) { - // DGF if the windows are incomparable, they're probably not the same... - } - } - if (isDom) { - return false; - } - var currentFrame; - eval("currentFrame=" + currentFrameString); - if (target == "relative=up") { - if (currentFrame.window.parent == autWindow) { - return true; - } - return false; - } - if (target == "relative=top") { - if (currentFrame.window.top == autWindow) { - return true; - } - return false; - } - if (currentFrame.window == autWindow.parent) { - if (autWindow.name == target) { - return true; - } - try { - var element = this.findElement(target, currentFrame.window); - if (element.contentWindow == autWindow) { - return true; - } - } catch (e) {} - } - return false; -}; - -BrowserBot.prototype.openLocation = function(target) { - // We're moving to a new page - clear the current one - var win = this.getCurrentWindow(); - LOG.debug("openLocation newPageLoaded = false"); - this.newPageLoaded = false; - - this.setOpenLocation(win, target); -}; - -BrowserBot.prototype.openWindow = function(url, windowID) { - if (url != "") { - url = absolutify(url, this.baseUrl); - } - if (browserVersion.isHTA) { - // in HTA mode, calling .open on the window interprets the url relative to that window - // we need to absolute-ize the URL to make it consistent - var child = this.getCurrentWindow().open(url, windowID); - selenium.browserbot.openedWindows[windowID] = child; - } else { - this.getCurrentWindow().open(url, windowID); - } -}; - -BrowserBot.prototype.setIFrameLocation = function(iframe, location) { - iframe.src = location; -}; - -BrowserBot.prototype.setOpenLocation = function(win, loc) { - loc = absolutify(loc, this.baseUrl); - if (browserVersion.isHTA) { - var oldHref = win.location.href; - win.location.href = loc; - var marker = null; - try { - marker = this.isPollingForLoad(win); - if (marker && win.location[marker]) { - win.location[marker] = false; - } - } catch (e) {} // DGF don't know why, but this often fails - } else { - win.location.href = loc; - } -}; - -BrowserBot.prototype.getCurrentPage = function() { - return this; -}; - -BrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - var self = this; - - windowToModify.seleniumAlert = windowToModify.alert; - - windowToModify.alert = function(alert) { - browserBot.recordedAlerts.push(alert); - self.relayBotToRC.call(self, "browserbot.recordedAlerts"); - }; - - windowToModify.confirm = function(message) { - browserBot.recordedConfirmations.push(message); - var result = browserBot.nextConfirmResult; - browserBot.nextConfirmResult = true; - self.relayBotToRC.call(self, "browserbot.recordedConfirmations"); - return result; - }; - - windowToModify.prompt = function(message) { - browserBot.recordedPrompts.push(message); - var result = !browserBot.nextConfirmResult ? null : browserBot.nextPromptResult; - browserBot.nextConfirmResult = true; - browserBot.nextPromptResult = ''; - self.relayBotToRC.call(self, "browserbot.recordedPrompts"); - return result; - }; - - // Keep a reference to all popup windows by name - // note that in IE the "windowName" argument must be a valid javascript identifier, it seems. - var originalOpen = windowToModify.open; - var originalOpenReference; - if (browserVersion.isHTA) { - originalOpenReference = 'selenium_originalOpen' + new Date().getTime(); - windowToModify[originalOpenReference] = windowToModify.open; - } - - var isHTA = browserVersion.isHTA; - - var newOpen = function(url, windowName, windowFeatures, replaceFlag) { - var myOriginalOpen = originalOpen; - if (isHTA) { - myOriginalOpen = this[originalOpenReference]; - } - if (windowName == "" || windowName == "_blank") { - windowName = "selenium_blank" + Math.round(100000 * Math.random()); - LOG.warn("Opening window '_blank', which is not a real window name. Randomizing target to be: " + windowName); - } - var openedWindow = myOriginalOpen(url, windowName, windowFeatures, replaceFlag); - LOG.debug("window.open call intercepted; window ID (which you can use with selectWindow()) is \"" + windowName + "\""); - if (windowName!=null) { - openedWindow["seleniumWindowName"] = windowName; - } - selenium.browserbot.openedWindows[windowName] = openedWindow; - return openedWindow; - }; - - if (browserVersion.isHTA) { - originalOpenReference = 'selenium_originalOpen' + new Date().getTime(); - newOpenReference = 'selenium_newOpen' + new Date().getTime(); - var setOriginalRef = "this['" + originalOpenReference + "'] = this.open;"; - - if (windowToModify.eval) { - windowToModify.eval(setOriginalRef); - windowToModify.open = newOpen; - } else { - // DGF why can't I eval here? Seems like I'm querying the window at a bad time, maybe? - setOriginalRef += "this.open = this['" + newOpenReference + "'];"; - windowToModify[newOpenReference] = newOpen; - windowToModify.setTimeout(setOriginalRef, 0); - } - } else { - windowToModify.open = newOpen; - } -}; - -/** - * Call the supplied function when a the current page unloads and a new one loads. - * This is done by polling continuously until the document changes and is fully loaded. - */ -BrowserBot.prototype.modifySeparateTestWindowToDetectPageLoads = function(windowObject) { - // Since the unload event doesn't fire in Safari 1.3, we start polling immediately - if (!windowObject) { - LOG.warn("modifySeparateTestWindowToDetectPageLoads: no windowObject!"); - return; - } - if (this._windowClosed(windowObject)) { - LOG.info("modifySeparateTestWindowToDetectPageLoads: windowObject was closed"); - return; - } - var oldMarker = this.isPollingForLoad(windowObject); - if (oldMarker) { - LOG.debug("modifySeparateTestWindowToDetectPageLoads: already polling this window: " + oldMarker); - return; - } - - var marker = 'selenium' + new Date().getTime(); - LOG.debug("Starting pollForLoad (" + marker + "): " + windowObject.location); - this.pollingForLoad[marker] = true; - // if this is a frame, add a load listener, otherwise, attach a poller - var frameElement = this._getFrameElement(windowObject); - // DGF HTA mode can't attach load listeners to subframes (yuk!) - var htaSubFrame = this._isHTASubFrame(windowObject); - if (frameElement && !htaSubFrame) { - LOG.debug("modifySeparateTestWindowToDetectPageLoads: this window is a frame; attaching a load listener"); - addLoadListener(frameElement, this.recordPageLoad); - frameElement[marker] = true; - frameElement["frame"+this.uniqueId] = marker; - LOG.debug("dgf this.uniqueId="+this.uniqueId); - LOG.debug("dgf marker="+marker); - LOG.debug("dgf frameElement['frame'+this.uniqueId]="+frameElement['frame'+this.uniqueId]); -frameElement[this.uniqueId] = marker; -LOG.debug("dgf frameElement[this.uniqueId]="+frameElement[this.uniqueId]); - } else { - windowObject.location[marker] = true; - windowObject[this.uniqueId] = marker; - this.pollForLoad(this.recordPageLoad, windowObject, windowObject.document, windowObject.location, windowObject.location.href, marker); - } -}; - -BrowserBot.prototype._isHTASubFrame = function(win) { - if (!browserVersion.isHTA) return false; - // DGF this is wrong! what if "win" isn't the selected window? - return this.isSubFrameSelected; -} - -BrowserBot.prototype._getFrameElement = function(win) { - var frameElement = null; - var caught; - try { - frameElement = win.frameElement; - } catch (e) { - caught = true; - } - if (caught) { - // on IE, checking frameElement in a pop-up results in a "No such interface supported" exception - // but it might have a frame element anyway! - var parentContainsIdenticallyNamedFrame = false; - try { - parentContainsIdenticallyNamedFrame = win.parent.frames[win.name]; - } catch (e) {} // this may fail if access is denied to the parent; in that case, assume it's not a pop-up - - if (parentContainsIdenticallyNamedFrame) { - // it can't be a coincidence that the parent has a frame with the same name as myself! - var result; - try { - result = parentContainsIdenticallyNamedFrame.frameElement; - if (result) { - return result; - } - } catch (e) {} // it was worth a try! _getFrameElementsByName is often slow - result = this._getFrameElementByName(win.name, win.parent.document, win); - return result; - } - } - LOG.debug("_getFrameElement: frameElement="+frameElement); - if (frameElement) { - LOG.debug("frameElement.name="+frameElement.name); - } - return frameElement; -} - -BrowserBot.prototype._getFrameElementByName = function(name, doc, win) { - var frames; - var frame; - var i; - frames = doc.getElementsByTagName("iframe"); - for (i = 0; i < frames.length; i++) { - frame = frames[i]; - if (frame.name === name) { - return frame; - } - } - frames = doc.getElementsByTagName("frame"); - for (i = 0; i < frames.length; i++) { - frame = frames[i]; - if (frame.name === name) { - return frame; - } - } - // DGF weird; we only call this function when we know the doc contains the frame - LOG.warn("_getFrameElementByName couldn't find a frame or iframe; checking every element for the name " + name); - return BrowserBot.prototype.locateElementByName(win.name, win.parent.document); -} - - -/** - * Set up a polling timer that will keep checking the readyState of the document until it's complete. - * Since we might call this before the original page is unloaded, we first check to see that the current location - * or href is different from the original one. - */ -BrowserBot.prototype.pollForLoad = function(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker) { - LOG.debug("pollForLoad original (" + marker + "): " + originalHref); - try { - if (this._windowClosed(windowObject)) { - LOG.debug("pollForLoad WINDOW CLOSED (" + marker + ")"); - delete this.pollingForLoad[marker]; - return; - } - - var isSamePage = this._isSamePage(windowObject, originalDocument, originalLocation, originalHref, marker); - var rs = this.getReadyState(windowObject, windowObject.document); - - if (!isSamePage && rs == 'complete') { - var currentHref = windowObject.location.href; - LOG.debug("pollForLoad FINISHED (" + marker + "): " + rs + " (" + currentHref + ")"); - delete this.pollingForLoad[marker]; - this._modifyWindow(windowObject); - var newMarker = this.isPollingForLoad(windowObject); - if (!newMarker) { - LOG.debug("modifyWindow didn't start new poller: " + newMarker); - this.modifySeparateTestWindowToDetectPageLoads(windowObject); - } - newMarker = this.isPollingForLoad(windowObject); - var currentlySelectedWindow; - var currentlySelectedWindowMarker; - currentlySelectedWindow =this.getCurrentWindow(true); - currentlySelectedWindowMarker = currentlySelectedWindow[this.uniqueId]; - - LOG.debug("pollForLoad (" + marker + ") restarting " + newMarker); - if (/(TestRunner-splash|Blank)\.html\?start=true$/.test(currentHref)) { - LOG.debug("pollForLoad Oh, it's just the starting page. Never mind!"); - } else if (currentlySelectedWindowMarker == newMarker) { - loadFunction(currentlySelectedWindow); - } else { - LOG.debug("pollForLoad page load detected in non-current window; ignoring (currentlySelected="+currentlySelectedWindowMarker+", detection in "+newMarker+")"); - } - return; - } - LOG.debug("pollForLoad continue (" + marker + "): " + currentHref); - this.reschedulePoller(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - } catch (e) { - LOG.debug("Exception during pollForLoad; this should get noticed soon (" + e.message + ")!"); - //DGF this is supposed to get logged later; log it at debug just in case - //LOG.exception(e); - this.pageLoadError = e; - } -}; - -BrowserBot.prototype._isSamePage = function(windowObject, originalDocument, originalLocation, originalHref, marker) { - var currentDocument = windowObject.document; - var currentLocation = windowObject.location; - var currentHref = currentLocation.href - - var sameDoc = this._isSameDocument(originalDocument, currentDocument); - - var sameLoc = (originalLocation === currentLocation); - - // hash marks don't meant the page has loaded, so we need to strip them off if they exist... - var currentHash = currentHref.indexOf('#'); - if (currentHash > 0) { - currentHref = currentHref.substring(0, currentHash); - } - var originalHash = originalHref.indexOf('#'); - if (originalHash > 0) { - originalHref = originalHref.substring(0, originalHash); - } - LOG.debug("_isSamePage: currentHref: " + currentHref); - LOG.debug("_isSamePage: originalHref: " + originalHref); - - var sameHref = (originalHref === currentHref); - var markedLoc = currentLocation[marker]; - - if (browserVersion.isKonqueror || browserVersion.isSafari) { - // the mark disappears too early on these browsers - markedLoc = true; - } - - // since this is some _very_ important logic, especially for PI and multiWindow mode, we should log all these out - LOG.debug("_isSamePage: sameDoc: " + sameDoc); - LOG.debug("_isSamePage: sameLoc: " + sameLoc); - LOG.debug("_isSamePage: sameHref: " + sameHref); - LOG.debug("_isSamePage: markedLoc: " + markedLoc); - - return sameDoc && sameLoc && sameHref && markedLoc -}; - -BrowserBot.prototype._isSameDocument = function(originalDocument, currentDocument) { - return originalDocument === currentDocument; -}; - - -BrowserBot.prototype.getReadyState = function(windowObject, currentDocument) { - var rs = currentDocument.readyState; - if (rs == null) { - if ((this.buttonWindow!=null && this.buttonWindow.document.readyState == null) // not proxy injection mode (and therefore buttonWindow isn't null) - || (top.document.readyState == null)) { // proxy injection mode (and therefore everything's in the top window, but buttonWindow doesn't exist) - // uh oh! we're probably on Firefox with no readyState extension installed! - // We'll have to just take a guess as to when the document is loaded; this guess - // will never be perfect. :-( - if (typeof currentDocument.getElementsByTagName != 'undefined' - && typeof currentDocument.getElementById != 'undefined' - && ( currentDocument.getElementsByTagName('body')[0] != null - || currentDocument.body != null )) { - if (windowObject.frameElement && windowObject.location.href == "about:blank" && windowObject.frameElement.src != "about:blank") { - LOG.info("getReadyState not loaded, frame location was about:blank, but frame src = " + windowObject.frameElement.src); - return null; - } - LOG.debug("getReadyState = windowObject.frames.length = " + windowObject.frames.length); - for (var i = 0; i < windowObject.frames.length; i++) { - LOG.debug("i = " + i); - if (this.getReadyState(windowObject.frames[i], windowObject.frames[i].document) != 'complete') { - LOG.debug("getReadyState aha! the nested frame " + windowObject.frames[i].name + " wasn't ready!"); - return null; - } - } - - rs = 'complete'; - } else { - LOG.debug("pollForLoad readyState was null and DOM appeared to not be ready yet"); - } - } - } - else if (rs == "loading" && browserVersion.isIE) { - LOG.debug("pageUnloading = true!!!!"); - this.pageUnloading = true; - } - LOG.debug("getReadyState returning " + rs); - return rs; -}; - -/** This function isn't used normally, but was the way we used to schedule pollers: - asynchronously executed autonomous units. This is deprecated, but remains here - for future reference. - */ -BrowserBot.prototype.XXXreschedulePoller = function(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker) { - var self = this; - window.setTimeout(function() { - self.pollForLoad(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - }, 500); -}; - -/** This function isn't used normally, but is useful for debugging asynchronous pollers - * To enable it, rename it to "reschedulePoller", so it will override the - * existing reschedulePoller function - */ -BrowserBot.prototype.XXXreschedulePoller = function(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker) { - var doc = this.buttonWindow.document; - var button = doc.createElement("button"); - var buttonName = doc.createTextNode(marker + " - " + windowObject.name); - button.appendChild(buttonName); - var tools = doc.getElementById("tools"); - var self = this; - button.onclick = function() { - tools.removeChild(button); - self.pollForLoad(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - }; - tools.appendChild(button); - window.setTimeout(button.onclick, 500); -}; - -BrowserBot.prototype.reschedulePoller = function(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker) { - var self = this; - var pollerFunction = function() { - self.pollForLoad(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - }; - this.windowPollers.push(pollerFunction); -}; - -BrowserBot.prototype.runScheduledPollers = function() { - LOG.debug("runScheduledPollers"); - var oldPollers = this.windowPollers; - this.windowPollers = new Array(); - for (var i = 0; i < oldPollers.length; i++) { - oldPollers[i].call(); - } - LOG.debug("runScheduledPollers DONE"); -}; - -BrowserBot.prototype.isPollingForLoad = function(win) { - var marker; - var frameElement = this._getFrameElement(win); - var htaSubFrame = this._isHTASubFrame(win); - if (frameElement && !htaSubFrame) { - marker = frameElement["frame"+this.uniqueId]; - } else { - marker = win[this.uniqueId]; - } - if (!marker) { - LOG.debug("isPollingForLoad false, missing uniqueId " + this.uniqueId + ": " + marker); - return false; - } - if (!this.pollingForLoad[marker]) { - LOG.debug("isPollingForLoad false, this.pollingForLoad[" + marker + "]: " + this.pollingForLoad[marker]); - return false; - } - return marker; -}; - -BrowserBot.prototype.getWindowByName = function(windowName, doNotModify) { - LOG.debug("getWindowByName(" + windowName + ")"); - // First look in the map of opened windows - var targetWindow = this.openedWindows[windowName]; - if (!targetWindow) { - targetWindow = this.topWindow[windowName]; - } - if (!targetWindow && windowName == "_blank") { - for (var winName in this.openedWindows) { - // _blank can match selenium_blank*, if it looks like it's OK (valid href, not closed) - if (/^selenium_blank/.test(winName)) { - targetWindow = this.openedWindows[winName]; - var ok; - try { - if (!this._windowClosed(targetWindow)) { - ok = targetWindow.location.href; - } - } catch (e) {} - if (ok) break; - } - } - } - if (!targetWindow) { - throw new SeleniumError("Window does not exist. If this looks like a Selenium bug, make sure to read http://selenium-core.openqa.org/reference.html#openWindow for potential workarounds."); - } - if (browserVersion.isHTA) { - try { - targetWindow.location.href; - } catch (e) { - targetWindow = window.open("", targetWindow.name); - this.openedWindows[targetWindow.name] = targetWindow; - } - } - if (!doNotModify) { - this._modifyWindow(targetWindow); - } - return targetWindow; -}; - -/** - * Find a window name from the window title. - */ -BrowserBot.prototype.getWindowNameByTitle = function(windowTitle) { - LOG.debug("getWindowNameByTitle(" + windowTitle + ")"); - - // First look in the map of opened windows and iterate them - for (var windowName in this.openedWindows) { - var targetWindow = this.openedWindows[windowName]; - - // If the target window's title is our title - try { - // TODO implement Pattern Matching here - if (!this._windowClosed(targetWindow) && - targetWindow.document.title == windowTitle) { - return windowName; - } - } catch (e) { - // You'll often get Permission Denied errors here in IE - // eh, if we can't read this window's title, - // it's probably not available to us right now anyway - } - } - - try { - if (this.topWindow.document.title == windowTitle) { - return ""; - } - } catch (e) {} // IE Perm denied - - throw new SeleniumError("Could not find window with title " + windowTitle); -}; - -BrowserBot.prototype.getCurrentWindow = function(doNotModify) { - if (this.proxyInjectionMode) { - return window; - } - var testWindow = this.currentWindow; - if (!doNotModify) { - this._modifyWindow(testWindow); - LOG.debug("getCurrentWindow newPageLoaded = false"); - this.newPageLoaded = false; - } - testWindow = this._handleClosedSubFrame(testWindow, doNotModify); - return testWindow; -}; - -/** - * Offer a method the end-user can reliably use to retrieve the current window. - * This should work even for windows with an XPCNativeWrapper. Returns the - * current window object. - */ -BrowserBot.prototype.getUserWindow = function() { - var userWindow = this.getCurrentWindow(true); - - if (userWindow.wrappedJSObject) { - userWindow = userWindow.wrappedJSObject; - } - - return userWindow; -}; - -BrowserBot.prototype._handleClosedSubFrame = function(testWindow, doNotModify) { - if (this.proxyInjectionMode) { - return testWindow; - } - - if (this.isSubFrameSelected) { - var missing = true; - if (testWindow.parent && testWindow.parent.frames && testWindow.parent.frames.length) { - for (var i = 0; i < testWindow.parent.frames.length; i++) { - if (testWindow.parent.frames[i] == testWindow) { - missing = false; - break; - } - } - } - if (missing) { - LOG.warn("Current subframe appears to have closed; selecting top frame"); - this.selectFrame("relative=top"); - return this.getCurrentWindow(doNotModify); - } - } else if (this._windowClosed(testWindow)) { - var closedError = new SeleniumError("Current window or frame is closed!"); - closedError.windowClosed = true; - throw closedError; - } - return testWindow; -}; - -BrowserBot.prototype.highlight = function (element, force) { - if (force || this.shouldHighlightLocatedElement) { - try { - highlight(element); - } catch (e) {} // DGF element highlighting is low-priority and possibly dangerous - } - return element; -} - -BrowserBot.prototype.setShouldHighlightElement = function (shouldHighlight) { - this.shouldHighlightLocatedElement = shouldHighlight; -} - -/*****************************************************************/ -/* BROWSER-SPECIFIC FUNCTIONS ONLY AFTER THIS LINE */ - - -BrowserBot.prototype._registerAllLocatorFunctions = function() { - // TODO - don't do this in the constructor - only needed once ever - this.locationStrategies = {}; - for (var functionName in this) { - var result = /^locateElementBy([A-Z].+)$/.exec(functionName); - if (result != null) { - var locatorFunction = this[functionName]; - if (typeof(locatorFunction) != 'function') { - continue; - } - // Use a specified prefix in preference to one generated from - // the function name - var locatorPrefix = locatorFunction.prefix || result[1].toLowerCase(); - this.locationStrategies[locatorPrefix] = locatorFunction; - } - } - - /** - * Find a locator based on a prefix. - */ - this.findElementBy = function(locatorType, locator, inDocument, inWindow) { - var locatorFunction = this.locationStrategies[locatorType]; - if (! locatorFunction) { - throw new SeleniumError("Unrecognised locator type: '" + locatorType + "'"); - } - return locatorFunction.call(this, locator, inDocument, inWindow); - }; - - /** - * The implicit locator, that is used when no prefix is supplied. - */ - this.locationStrategies['implicit'] = function(locator, inDocument, inWindow) { - if (locator.startsWith('//')) { - return this.locateElementByXPath(locator, inDocument, inWindow); - } - if (locator.startsWith('document.')) { - return this.locateElementByDomTraversal(locator, inDocument, inWindow); - } - return this.locateElementByIdentifier(locator, inDocument, inWindow); - }; -} - -BrowserBot.prototype.getDocument = function() { - return this.getCurrentWindow().document; -} - -BrowserBot.prototype.getTitle = function() { - var t = this.getDocument().title; - if (typeof(t) == "string") { - t = t.trim(); - } - return t; -} - -BrowserBot.prototype.getCookieByName = function(cookieName, doc) { - if (!doc) doc = this.getDocument(); - var ck = doc.cookie; - if (!ck) return null; - var ckPairs = ck.split(/;/); - for (var i = 0; i < ckPairs.length; i++) { - var ckPair = ckPairs[i].trim(); - var ckNameValue = ckPair.split(/=/); - var ckName = decodeURIComponent(ckNameValue[0]); - if (ckName === cookieName) { - return decodeURIComponent(ckNameValue[1]); - } - } - return null; -} - -BrowserBot.prototype.getAllCookieNames = function(doc) { - if (!doc) doc = this.getDocument(); - var ck = doc.cookie; - if (!ck) return []; - var cookieNames = []; - var ckPairs = ck.split(/;/); - for (var i = 0; i < ckPairs.length; i++) { - var ckPair = ckPairs[i].trim(); - var ckNameValue = ckPair.split(/=/); - var ckName = decodeURIComponent(ckNameValue[0]); - cookieNames.push(ckName); - } - return cookieNames; -} - -BrowserBot.prototype.deleteCookie = function(cookieName, domain, path, doc) { - if (!doc) doc = this.getDocument(); - var expireDateInMilliseconds = (new Date()).getTime() + (-1 * 1000); - var cookie = cookieName + "=deleted; "; - if (path) { - cookie += "path=" + path + "; "; - } - if (domain) { - cookie += "domain=" + domain + "; "; - } - cookie += "expires=" + new Date(expireDateInMilliseconds).toGMTString(); - LOG.debug("Setting cookie to: " + cookie); - doc.cookie = cookie; -} - -/** Try to delete cookie, return false if it didn't work */ -BrowserBot.prototype._maybeDeleteCookie = function(cookieName, domain, path, doc) { - this.deleteCookie(cookieName, domain, path, doc); - return (!this.getCookieByName(cookieName, doc)); -} - - -BrowserBot.prototype._recursivelyDeleteCookieDomains = function(cookieName, domain, path, doc) { - var deleted = this._maybeDeleteCookie(cookieName, domain, path, doc); - if (deleted) return true; - var dotIndex = domain.indexOf("."); - if (dotIndex == 0) { - return this._recursivelyDeleteCookieDomains(cookieName, domain.substring(1), path, doc); - } else if (dotIndex != -1) { - return this._recursivelyDeleteCookieDomains(cookieName, domain.substring(dotIndex), path, doc); - } else { - // No more dots; try just not passing in a domain at all - return this._maybeDeleteCookie(cookieName, null, path, doc); - } -} - -BrowserBot.prototype._recursivelyDeleteCookie = function(cookieName, domain, path, doc) { - var slashIndex = path.lastIndexOf("/"); - var finalIndex = path.length-1; - if (slashIndex == finalIndex) { - slashIndex--; - } - if (slashIndex != -1) { - deleted = this._recursivelyDeleteCookie(cookieName, domain, path.substring(0, slashIndex+1), doc); - if (deleted) return true; - } - return this._recursivelyDeleteCookieDomains(cookieName, domain, path, doc); -} - -BrowserBot.prototype.recursivelyDeleteCookie = function(cookieName, domain, path, win) { - if (!win) win = this.getCurrentWindow(); - var doc = win.document; - if (!domain) { - domain = doc.domain; - } - if (!path) { - path = win.location.pathname; - } - var deleted = this._recursivelyDeleteCookie(cookieName, "." + domain, path, doc); - if (deleted) return; - // Finally try a null path (Try it last because it's uncommon) - deleted = this._recursivelyDeleteCookieDomains(cookieName, "." + domain, null, doc); - if (deleted) return; - throw new SeleniumError("Couldn't delete cookie " + cookieName); -} - -/* - * Finds an element recursively in frames and nested frames - * in the specified document, using various lookup protocols - */ -BrowserBot.prototype.findElementRecursive = function(locatorType, locatorString, inDocument, inWindow) { - - var element = this.findElementBy(locatorType, locatorString, inDocument, inWindow); - if (element != null) { - return element; - } - - for (var i = 0; i < inWindow.frames.length; i++) { - // On some browsers, the document object is undefined for third-party - // frames. Make sure the document is valid before continuing. - if (inWindow.frames[i].document) { - element = this.findElementRecursive(locatorType, locatorString, inWindow.frames[i].document, inWindow.frames[i]); - - if (element != null) { - return element; - } - } - } -}; - -/* -* Finds an element on the current page, using various lookup protocols -*/ -BrowserBot.prototype.findElementOrNull = function(locator, win) { - locator = parse_locator(locator); - - if (win == null) { - win = this.getCurrentWindow(); - } - var element = this.findElementRecursive(locator.type, locator.string, win.document, win); - - if (element != null) { - return this.browserbot.highlight(element); - } - - // Element was not found by any locator function. - return null; -}; - -BrowserBot.prototype.findElement = function(locator, win) { - var element = this.findElementOrNull(locator, win); - if (element == null) throw new SeleniumError("Element " + locator + " not found"); - return element; -} - -/** - * In non-IE browsers, getElementById() does not search by name. Instead, we - * we search separately by id and name. - */ -BrowserBot.prototype.locateElementByIdentifier = function(identifier, inDocument, inWindow) { - return BrowserBot.prototype.locateElementById(identifier, inDocument, inWindow) - || BrowserBot.prototype.locateElementByName(identifier, inDocument, inWindow) - || null; -}; - -/** - * Find the element with id - can't rely on getElementById, coz it returns by name as well in IE.. - */ -BrowserBot.prototype.locateElementById = function(identifier, inDocument, inWindow) { - var element = inDocument.getElementById(identifier); - if (element && element.getAttribute('id') === identifier) { - return element; - } - else if (browserVersion.isIE || browserVersion.isOpera) { - // SEL-484 - var xpath = '/descendant::*[@id=' + identifier.quoteForXPath() + ']'; - return BrowserBot.prototype - .locateElementByXPath(xpath, inDocument, inWindow); - } - else { - return null; - } -}; - -/** - * Find an element by name, refined by (optional) element-filter - * expressions. - */ -BrowserBot.prototype.locateElementByName = function(locator, document, inWindow) { - var elements = document.getElementsByTagName("*"); - - var filters = locator.split(' '); - filters[0] = 'name=' + filters[0]; - - while (filters.length) { - var filter = filters.shift(); - elements = this.selectElements(filter, elements, 'value'); - } - - if (elements.length > 0) { - return elements[0]; - } - return null; -}; - -/** - * Finds an element using by evaluating the specfied string. - */ -BrowserBot.prototype.locateElementByDomTraversal = function(domTraversal, document, window) { - - var browserbot = this.browserbot; - var element = null; - try { - element = eval(domTraversal); - } catch (e) { - return null; - } - - if (!element) { - return null; - } - - return element; -}; -BrowserBot.prototype.locateElementByDomTraversal.prefix = "dom"; - -/** - * Finds an element identified by the xpath expression. Expressions _must_ - * begin with "//". - */ -BrowserBot.prototype.locateElementByXPath = function(xpath, inDocument, inWindow) { - var results = eval_xpath(xpath, inDocument, { - returnOnFirstMatch : true, - ignoreAttributesWithoutValue: this.ignoreAttributesWithoutValue, - allowNativeXpath : this.allowNativeXpath, - xpathLibrary : this.xpathLibrary, - namespaceResolver : this._namespaceResolver - }); - return (results.length > 0) ? results[0] : null; -}; - -BrowserBot.prototype._namespaceResolver = function(prefix) { - if (prefix == 'html' || prefix == 'xhtml' || prefix == 'x') { - return 'http://www.w3.org/1999/xhtml'; - } else if (prefix == 'mathml') { - return 'http://www.w3.org/1998/Math/MathML'; - } else { - throw new Error("Unknown namespace: " + prefix + "."); - } -} - -/** - * Returns the number of xpath results. - */ -BrowserBot.prototype.evaluateXPathCount = function(xpath, inDocument) { - var results = eval_xpath(xpath, inDocument, { - ignoreAttributesWithoutValue: this.ignoreAttributesWithoutValue, - allowNativeXpath : this.allowNativeXpath, - xpathLibrary : this.xpathLibrary, - namespaceResolver : this._namespaceResolver - }); - return results.length; -}; - -/** - * Finds a link element with text matching the expression supplied. Expressions must - * begin with "link:". - */ -BrowserBot.prototype.locateElementByLinkText = function(linkText, inDocument, inWindow) { - var links = inDocument.getElementsByTagName('a'); - for (var i = 0; i < links.length; i++) { - var element = links[i]; - if (PatternMatcher.matches(linkText, getText(element))) { - return element; - } - } - return null; -}; -BrowserBot.prototype.locateElementByLinkText.prefix = "link"; - -/** - * Returns an attribute based on an attribute locator. This is made up of an element locator - * suffixed with @attribute-name. - */ -BrowserBot.prototype.findAttribute = function(locator) { - // Split into locator + attributeName - var attributePos = locator.lastIndexOf("@"); - var elementLocator = locator.slice(0, attributePos); - var attributeName = locator.slice(attributePos + 1); - - // Find the element. - var element = this.findElement(elementLocator); - - // Handle missing "class" attribute in IE. - if (browserVersion.isIE && attributeName == "class") { - attributeName = "className"; - } - - // Get the attribute value. - var attributeValue = element.getAttribute(attributeName); - - // IE returns an object for the "style" attribute - if (attributeName == 'style' && typeof(attributeValue) != 'string') { - attributeValue = attributeValue.cssText; - } - - return attributeValue ? attributeValue.toString() : null; -}; - -/* -* Select the specified option and trigger the relevant events of the element. -*/ -BrowserBot.prototype.selectOption = function(element, optionToSelect) { - triggerEvent(element, 'focus', false); - var changed = false; - for (var i = 0; i < element.options.length; i++) { - var option = element.options[i]; - if (option.selected && option != optionToSelect) { - option.selected = false; - changed = true; - } - else if (!option.selected && option == optionToSelect) { - option.selected = true; - changed = true; - } - } - - if (changed) { - triggerEvent(element, 'change', true); - } -}; - -/* -* Select the specified option and trigger the relevant events of the element. -*/ -BrowserBot.prototype.addSelection = function(element, option) { - this.checkMultiselect(element); - triggerEvent(element, 'focus', false); - if (!option.selected) { - option.selected = true; - triggerEvent(element, 'change', true); - } -}; - -/* -* Select the specified option and trigger the relevant events of the element. -*/ -BrowserBot.prototype.removeSelection = function(element, option) { - this.checkMultiselect(element); - triggerEvent(element, 'focus', false); - if (option.selected) { - option.selected = false; - triggerEvent(element, 'change', true); - } -}; - -BrowserBot.prototype.checkMultiselect = function(element) { - if (!element.multiple) - { - throw new SeleniumError("Not a multi-select"); - } - -}; - -BrowserBot.prototype.replaceText = function(element, stringValue) { - triggerEvent(element, 'focus', false); - triggerEvent(element, 'select', true); - var maxLengthAttr = element.getAttribute("maxLength"); - var actualValue = stringValue; - if (maxLengthAttr != null) { - var maxLength = parseInt(maxLengthAttr); - if (stringValue.length > maxLength) { - actualValue = stringValue.substr(0, maxLength); - } - } - - if (getTagName(element) == "body") { - if (element.ownerDocument && element.ownerDocument.designMode) { - var designMode = new String(element.ownerDocument.designMode).toLowerCase(); - if (designMode = "on") { - // this must be a rich text control! - element.innerHTML = actualValue; - } - } - } else { - element.value = actualValue; - } - // DGF this used to be skipped in chrome URLs, but no longer. Is xpcnativewrappers to blame? - try { - triggerEvent(element, 'change', true); - } catch (e) {} -}; - -BrowserBot.prototype.submit = function(formElement) { - var actuallySubmit = true; - this._modifyElementTarget(formElement); - if (formElement.onsubmit) { - if (browserVersion.isHTA) { - // run the code in the correct window so alerts are handled correctly even in HTA mode - var win = this.browserbot.getCurrentWindow(); - var now = new Date().getTime(); - var marker = 'marker' + now; - win[marker] = formElement; - win.setTimeout("var actuallySubmit = "+marker+".onsubmit();" + - "if (actuallySubmit) { " + - marker+".submit(); " + - "if ("+marker+".target && !/^_/.test("+marker+".target)) {"+ - "window.open('', "+marker+".target);"+ - "}"+ - "};"+ - marker+"=null", 0); - // pause for up to 2s while this command runs - var terminationCondition = function () { - return !win[marker]; - } - return Selenium.decorateFunctionWithTimeout(terminationCondition, 2000); - } else { - actuallySubmit = formElement.onsubmit(); - if (actuallySubmit) { - formElement.submit(); - if (formElement.target && !/^_/.test(formElement.target)) { - this.browserbot.openWindow('', formElement.target); - } - } - } - } else { - formElement.submit(); - } -} - -BrowserBot.prototype.clickElement = function(element, clientX, clientY) { - this._fireEventOnElement("click", element, clientX, clientY); -}; - -BrowserBot.prototype.doubleClickElement = function(element, clientX, clientY) { - this._fireEventOnElement("dblclick", element, clientX, clientY); -}; - -// The contextmenu event is fired when the user right-clicks to open the context menu -BrowserBot.prototype.contextMenuOnElement = function(element, clientX, clientY) { - this._fireEventOnElement("contextmenu", element, clientX, clientY); -}; - -BrowserBot.prototype._modifyElementTarget = function(element) { - if (element.target) { - if (element.target == "_blank" || /^selenium_blank/.test(element.target) ) { - var tagName = getTagName(element); - if (tagName == "a" || tagName == "form") { - var newTarget = "selenium_blank" + Math.round(100000 * Math.random()); - LOG.warn("Link has target '_blank', which is not supported in Selenium! Randomizing target to be: " + newTarget); - this.browserbot.openWindow('', newTarget); - element.target = newTarget; - } - } - } -} - - -BrowserBot.prototype._handleClickingImagesInsideLinks = function(targetWindow, element) { - var itrElement = element; - while (itrElement != null) { - if (itrElement.href) { - targetWindow.location.href = itrElement.href; - break; - } - itrElement = itrElement.parentNode; - } -} - -BrowserBot.prototype._getTargetWindow = function(element) { - var targetWindow = element.ownerDocument.defaultView; - if (element.target) { - targetWindow = this._getFrameFromGlobal(element.target); - } - return targetWindow; -} - -BrowserBot.prototype._getFrameFromGlobal = function(target) { - - if (target == "_self") { - return this.getCurrentWindow(); - } - if (target == "_top") { - return this.topFrame; - } else if (target == "_parent") { - return this.getCurrentWindow().parent; - } else if (target == "_blank") { - // TODO should this set cleverer window defaults? - return this.getCurrentWindow().open('', '_blank'); - } - var frameElement = this.findElementBy("implicit", target, this.topFrame.document, this.topFrame); - if (frameElement) { - return frameElement.contentWindow; - } - var win = this.getWindowByName(target); - if (win) return win; - return this.getCurrentWindow().open('', target); -} - - -BrowserBot.prototype.bodyText = function() { - if (!this.getDocument().body) { - throw new SeleniumError("Couldn't access document.body. Is this HTML page fully loaded?"); - } - return getText(this.getDocument().body); -}; - -BrowserBot.prototype.getAllButtons = function() { - var elements = this.getDocument().getElementsByTagName('input'); - var result = []; - - for (var i = 0; i < elements.length; i++) { - if (elements[i].type == 'button' || elements[i].type == 'submit' || elements[i].type == 'reset') { - result.push(elements[i].id); - } - } - - return result; -}; - - -BrowserBot.prototype.getAllFields = function() { - var elements = this.getDocument().getElementsByTagName('input'); - var result = []; - - for (var i = 0; i < elements.length; i++) { - if (elements[i].type == 'text') { - result.push(elements[i].id); - } - } - - return result; -}; - -BrowserBot.prototype.getAllLinks = function() { - var elements = this.getDocument().getElementsByTagName('a'); - var result = []; - - for (var i = 0; i < elements.length; i++) { - result.push(elements[i].id); - } - - return result; -}; - -function isDefined(value) { - return typeof(value) != undefined; -} - -BrowserBot.prototype.goBack = function() { - this.getCurrentWindow().history.back(); -}; - -BrowserBot.prototype.goForward = function() { - this.getCurrentWindow().history.forward(); -}; - -BrowserBot.prototype.close = function() { - if (browserVersion.isIE) { - // fix "do you want to close this window" warning in IE - // You can only close windows that you have opened. - // So, let's "open" it. - try { - this.topFrame.name=new Date().getTime(); - window.open("", this.topFrame.name, ""); - this.topFrame.close(); - return; - } catch (e) {} - } - if (browserVersion.isChrome || browserVersion.isSafari || browserVersion.isOpera) { - this.topFrame.close(); - } else { - this.getCurrentWindow().eval("window.top.close();"); - } -}; - -BrowserBot.prototype.refresh = function() { - this.getCurrentWindow().location.reload(true); -}; - -/** - * Refine a list of elements using a filter. - */ -BrowserBot.prototype.selectElementsBy = function(filterType, filter, elements) { - var filterFunction = BrowserBot.filterFunctions[filterType]; - if (! filterFunction) { - throw new SeleniumError("Unrecognised element-filter type: '" + filterType + "'"); - } - - return filterFunction(filter, elements); -}; - -BrowserBot.filterFunctions = {}; - -BrowserBot.filterFunctions.name = function(name, elements) { - var selectedElements = []; - for (var i = 0; i < elements.length; i++) { - if (elements[i].name === name) { - selectedElements.push(elements[i]); - } - } - return selectedElements; -}; - -BrowserBot.filterFunctions.value = function(value, elements) { - var selectedElements = []; - for (var i = 0; i < elements.length; i++) { - if (elements[i].value === value) { - selectedElements.push(elements[i]); - } - } - return selectedElements; -}; - -BrowserBot.filterFunctions.index = function(index, elements) { - index = Number(index); - if (isNaN(index) || index < 0) { - throw new SeleniumError("Illegal Index: " + index); - } - if (elements.length <= index) { - throw new SeleniumError("Index out of range: " + index); - } - return [elements[index]]; -}; - -BrowserBot.prototype.selectElements = function(filterExpr, elements, defaultFilterType) { - - var filterType = (defaultFilterType || 'value'); - - // If there is a filter prefix, use the specified strategy - var result = filterExpr.match(/^([A-Za-z]+)=(.+)/); - if (result) { - filterType = result[1].toLowerCase(); - filterExpr = result[2]; - } - - return this.selectElementsBy(filterType, filterExpr, elements); -}; - -/** - * Find an element by class - */ -BrowserBot.prototype.locateElementByClass = function(locator, document) { - return elementFindFirstMatchingChild(document, - function(element) { - return element.className == locator - } - ); -} - -/** - * Find an element by alt - */ -BrowserBot.prototype.locateElementByAlt = function(locator, document) { - return elementFindFirstMatchingChild(document, - function(element) { - return element.alt == locator - } - ); -} - -/** - * Find an element by css selector - */ -BrowserBot.prototype.locateElementByCss = function(locator, document) { - var elements = eval_css(locator, document); - if (elements.length != 0) - return elements[0]; - return null; -} - -/** - * This function is responsible for mapping a UI specifier string to an element - * on the page, and returning it. If no element is found, null is returned. - * Returning null on failure to locate the element is part of the undocumented - * API for locator strategies. - */ -BrowserBot.prototype.locateElementByUIElement = function(locator, inDocument) { - // offset locators are delimited by "->", which is much simpler than the - // previous scheme involving detecting the close-paren. - var locators = locator.split(/->/, 2); - - var locatedElement = null; - var pageElements = UIMap.getInstance() - .getPageElements(locators[0], inDocument); - - if (locators.length > 1) { - for (var i = 0; i < pageElements.length; ++i) { - var locatedElements = eval_locator(locators[1], inDocument, - pageElements[i]); - if (locatedElements.length) { - locatedElement = locatedElements[0]; - break; - } - } - } - else if (pageElements.length) { - locatedElement = pageElements[0]; - } - - return locatedElement; -} - -BrowserBot.prototype.locateElementByUIElement.prefix = 'ui'; - -// define a function used to compare the result of a close UI element -// match with the actual interacted element. If they are close enough -// according to the heuristic, consider them a match. -/** - * A heuristic function for comparing a node with a target node. Typically the - * node is specified in a UI element definition, while the target node is - * returned by the recorder as the leaf element which had some event enacted - * upon it. This particular heuristic covers the case where the anchor element - * contains other inline tags, such as "em" or "img". - * - * @param node the node being compared to the target node - * @param target the target node - * @return true if node equals target, or if node is a link - * element and target is its descendant, or if node has - * an onclick attribute and target is its descendant. - * False otherwise. - */ -BrowserBot.prototype.locateElementByUIElement.is_fuzzy_match = function(node, target) { - try { - var isMatch = ( - (node == target) || - ((node.nodeName == 'A' || node.onclick) && is_ancestor(node, target)) - ); - return isMatch; - } - catch (e) { - return false; - } -}; - -/*****************************************************************/ -/* BROWSER-SPECIFIC FUNCTIONS ONLY AFTER THIS LINE */ - -function MozillaBrowserBot(frame) { - BrowserBot.call(this, frame); -} -objectExtend(MozillaBrowserBot.prototype, BrowserBot.prototype); - -function KonquerorBrowserBot(frame) { - BrowserBot.call(this, frame); -} -objectExtend(KonquerorBrowserBot.prototype, BrowserBot.prototype); - -KonquerorBrowserBot.prototype.setIFrameLocation = function(iframe, location) { - // Window doesn't fire onload event when setting src to the current value, - // so we set it to blank first. - iframe.src = "about:blank"; - iframe.src = location; -}; - -KonquerorBrowserBot.prototype.setOpenLocation = function(win, loc) { - // Window doesn't fire onload event when setting src to the current value, - // so we just refresh in that case instead. - loc = absolutify(loc, this.baseUrl); - loc = canonicalize(loc); - var startUrl = win.location.href; - if ("about:blank" != win.location.href) { - var startLoc = parseUrl(win.location.href); - startLoc.hash = null; - var startUrl = reassembleLocation(startLoc); - } - LOG.debug("startUrl="+startUrl); - LOG.debug("win.location.href="+win.location.href); - LOG.debug("loc="+loc); - if (startUrl == loc) { - LOG.debug("opening exact same location"); - this.refresh(); - } else { - LOG.debug("locations differ"); - win.location.href = loc; - } - // force the current polling thread to detect a page load - var marker = this.isPollingForLoad(win); - if (marker) { - delete win.location[marker]; - } -}; - -KonquerorBrowserBot.prototype._isSameDocument = function(originalDocument, currentDocument) { - // under Konqueror, there may be this case: - // originalDocument and currentDocument are different objects - // while their location are same. - if (originalDocument) { - return originalDocument.location == currentDocument.location - } else { - return originalDocument === currentDocument; - } -}; - -function SafariBrowserBot(frame) { - BrowserBot.call(this, frame); -} -objectExtend(SafariBrowserBot.prototype, BrowserBot.prototype); - -SafariBrowserBot.prototype.setIFrameLocation = KonquerorBrowserBot.prototype.setIFrameLocation; -SafariBrowserBot.prototype.setOpenLocation = KonquerorBrowserBot.prototype.setOpenLocation; - - -function OperaBrowserBot(frame) { - BrowserBot.call(this, frame); -} -objectExtend(OperaBrowserBot.prototype, BrowserBot.prototype); -OperaBrowserBot.prototype.setIFrameLocation = function(iframe, location) { - if (iframe.src == location) { - iframe.src = location + '?reload'; - } else { - iframe.src = location; - } -} - -function IEBrowserBot(frame) { - BrowserBot.call(this, frame); -} -objectExtend(IEBrowserBot.prototype, BrowserBot.prototype); - -IEBrowserBot.prototype._handleClosedSubFrame = function(testWindow, doNotModify) { - if (this.proxyInjectionMode) { - return testWindow; - } - - try { - testWindow.location.href; - this.permDenied = 0; - } catch (e) { - this.permDenied++; - } - if (this._windowClosed(testWindow) || this.permDenied > 4) { - if (this.isSubFrameSelected) { - LOG.warn("Current subframe appears to have closed; selecting top frame"); - this.selectFrame("relative=top"); - return this.getCurrentWindow(doNotModify); - } else { - var closedError = new SeleniumError("Current window or frame is closed!"); - closedError.windowClosed = true; - throw closedError; - } - } - return testWindow; -}; - -IEBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot); - - // we will call the previous version of this method from within our own interception - oldShowModalDialog = windowToModify.showModalDialog; - - windowToModify.showModalDialog = function(url, args, features) { - // Get relative directory to where TestRunner.html lives - // A risky assumption is that the user's TestRunner is named TestRunner.html - var doc_location = document.location.toString(); - var end_of_base_ref = doc_location.indexOf('TestRunner.html'); - var base_ref = doc_location.substring(0, end_of_base_ref); - var runInterval = ''; - - // Only set run interval if options is defined - if (typeof(window.runOptions) != 'undefined') { - runInterval = "&runInterval=" + runOptions.runInterval; - } - - var testRunnerURL = "TestRunner.html?auto=true&singletest=" - + escape(browserBot.modalDialogTest) - + "&autoURL=" - + escape(url) - + runInterval; - var fullURL = base_ref + testRunnerURL; - browserBot.modalDialogTest = null; - - // If using proxy injection mode - if (this.proxyInjectionMode) { - var sessionId = runOptions.getSessionId(); - if (sessionId == undefined) { - sessionId = injectedSessionId; - } - if (sessionId != undefined) { - LOG.debug("Invoking showModalDialog and injecting URL " + fullURL); - } - fullURL = url; - } - var returnValue = oldShowModalDialog(fullURL, args, features); - return returnValue; - }; -}; - -IEBrowserBot.prototype.modifySeparateTestWindowToDetectPageLoads = function(windowObject) { - this.pageUnloading = false; - var self = this; - var pageUnloadDetector = function() { - self.pageUnloading = true; - }; - windowObject.attachEvent("onbeforeunload", pageUnloadDetector); - BrowserBot.prototype.modifySeparateTestWindowToDetectPageLoads.call(this, windowObject); -}; - -IEBrowserBot.prototype.pollForLoad = function(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker) { - LOG.debug("IEBrowserBot.pollForLoad: " + marker); - if (!this.permDeniedCount[marker]) this.permDeniedCount[marker] = 0; - BrowserBot.prototype.pollForLoad.call(this, loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - if (this.pageLoadError) { - if (this.pageUnloading) { - var self = this; - LOG.debug("pollForLoad UNLOADING (" + marker + "): caught exception while firing events on unloading page: " + this.pageLoadError.message); - this.reschedulePoller(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - this.pageLoadError = null; - return; - } else if (((this.pageLoadError.message == "Permission denied") || (/^Access is denied/.test(this.pageLoadError.message))) - && this.permDeniedCount[marker]++ < 8) { - if (this.permDeniedCount[marker] > 4) { - var canAccessThisWindow; - var canAccessCurrentlySelectedWindow; - try { - windowObject.location.href; - canAccessThisWindow = true; - } catch (e) {} - try { - this.getCurrentWindow(true).location.href; - canAccessCurrentlySelectedWindow = true; - } catch (e) {} - if (canAccessCurrentlySelectedWindow & !canAccessThisWindow) { - LOG.debug("pollForLoad (" + marker + ") ABORTING: " + this.pageLoadError.message + " (" + this.permDeniedCount[marker] + "), but the currently selected window is fine"); - // returning without rescheduling - this.pageLoadError = null; - return; - } - } - - var self = this; - LOG.debug("pollForLoad (" + marker + "): " + this.pageLoadError.message + " (" + this.permDeniedCount[marker] + "), waiting to see if it goes away"); - this.reschedulePoller(loadFunction, windowObject, originalDocument, originalLocation, originalHref, marker); - this.pageLoadError = null; - return; - } - //handy for debugging! - //throw this.pageLoadError; - } -}; - -IEBrowserBot.prototype._windowClosed = function(win) { - try { - var c = win.closed; - // frame windows claim to be non-closed when their parents are closed - // but you can't access their document objects in that case - if (!c) { - try { - win.document; - } catch (de) { - if (de.message == "Permission denied") { - // the window is probably unloading, which means it's probably not closed yet - return false; - } - else if (/^Access is denied/.test(de.message)) { - // rare variation on "Permission denied"? - LOG.debug("IEBrowserBot.windowClosed: got " + de.message + " (this.pageUnloading=" + this.pageUnloading + "); assuming window is unloading, probably not closed yet"); - return false; - } else { - // this is probably one of those frame window situations - LOG.debug("IEBrowserBot.windowClosed: couldn't read win.document, assume closed: " + de.message + " (this.pageUnloading=" + this.pageUnloading + ")"); - return true; - } - } - } - if (c == null) { - LOG.debug("IEBrowserBot.windowClosed: win.closed was null, assuming closed"); - return true; - } - return c; - } catch (e) { - LOG.debug("IEBrowserBot._windowClosed: Got an exception trying to read win.closed; we'll have to take a guess!"); - - if (browserVersion.isHTA) { - if (e.message == "Permission denied") { - // the window is probably unloading, which means it's not closed yet - return false; - } else { - // there's a good chance that we've lost contact with the window object if it is closed - return true; - } - } else { - // the window is probably unloading, which means it's not closed yet - return false; - } - } -}; - -/** - * In IE, getElementById() also searches by name - this is an optimisation for IE. - */ -IEBrowserBot.prototype.locateElementByIdentifer = function(identifier, inDocument, inWindow) { - return inDocument.getElementById(identifier); -}; - -SafariBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot); - - var originalOpen = windowToModify.open; - /* - * Safari seems to be broken, so that when we manually trigger the onclick method - * of a button/href, any window.open calls aren't resolved relative to the app location. - * So here we replace the open() method with one that does resolve the url correctly. - */ - windowToModify.open = function(url, windowName, windowFeatures, replaceFlag) { - - if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("/")) { - return originalOpen(url, windowName, windowFeatures, replaceFlag); - } - - // Reduce the current path to the directory - var currentPath = windowToModify.location.pathname || "/"; - currentPath = currentPath.replace(/\/[^\/]*$/, "/"); - - // Remove any leading "./" from the new url. - url = url.replace(/^\.\//, ""); - - newUrl = currentPath + url; - - var openedWindow = originalOpen(newUrl, windowName, windowFeatures, replaceFlag); - LOG.debug("window.open call intercepted; window ID (which you can use with selectWindow()) is \"" + windowName + "\""); - if (windowName!=null) { - openedWindow["seleniumWindowName"] = windowName; - } - return openedWindow; - }; -}; - -MozillaBrowserBot.prototype._fireEventOnElement = function(eventType, element, clientX, clientY) { - var win = this.getCurrentWindow(); - triggerEvent(element, 'focus', false); - - // Add an event listener that detects if the default action has been prevented. - // (This is caused by a javascript onclick handler returning false) - // we capture the whole event, rather than the getPreventDefault() state at the time, - // because we need to let the entire event bubbling and capturing to go through - // before making a decision on whether we should force the href - var savedEvent = null; - - element.addEventListener(eventType, function(evt) { - savedEvent = evt; - }, false); - - this._modifyElementTarget(element); - - // Trigger the event. - this.browserbot.triggerMouseEvent(element, eventType, true, clientX, clientY); - - if (this._windowClosed(win)) { - return; - } - - // Perform the link action if preventDefault was set. - // In chrome URL, the link action is already executed by triggerMouseEvent. - if (!browserVersion.isChrome && savedEvent != null && !savedEvent.getPreventDefault()) { - var targetWindow = this.browserbot._getTargetWindow(element); - if (element.href) { - targetWindow.location.href = element.href; - } else { - this.browserbot._handleClickingImagesInsideLinks(targetWindow, element); - } - } - -}; - - -OperaBrowserBot.prototype._fireEventOnElement = function(eventType, element, clientX, clientY) { - var win = this.getCurrentWindow(); - triggerEvent(element, 'focus', false); - - this._modifyElementTarget(element); - - // Trigger the click event. - this.browserbot.triggerMouseEvent(element, eventType, true, clientX, clientY); - - if (this._windowClosed(win)) { - return; - } - -}; - - -KonquerorBrowserBot.prototype._fireEventOnElement = function(eventType, element, clientX, clientY) { - var win = this.getCurrentWindow(); - triggerEvent(element, 'focus', false); - - this._modifyElementTarget(element); - - if (element[eventType]) { - element[eventType](); - } - else { - this.browserbot.triggerMouseEvent(element, eventType, true, clientX, clientY); - } - - if (this._windowClosed(win)) { - return; - } - -}; - -SafariBrowserBot.prototype._fireEventOnElement = function(eventType, element, clientX, clientY) { - triggerEvent(element, 'focus', false); - var wasChecked = element.checked; - - this._modifyElementTarget(element); - - // For form element it is simple. - if (element[eventType]) { - element[eventType](); - } - // For links and other elements, event emulation is required. - else { - var targetWindow = this.browserbot._getTargetWindow(element); - // todo: deal with anchors? - this.browserbot.triggerMouseEvent(element, eventType, true, clientX, clientY); - - } - -}; - -SafariBrowserBot.prototype.refresh = function() { - var win = this.getCurrentWindow(); - if (win.location.hash) { - // DGF Safari refuses to refresh when there's a hash symbol in the URL - win.location.hash = ""; - var actuallyReload = function() { - win.location.reload(true); - } - window.setTimeout(actuallyReload, 1); - } else { - win.location.reload(true); - } -}; - -IEBrowserBot.prototype._fireEventOnElement = function(eventType, element, clientX, clientY) { - var win = this.getCurrentWindow(); - triggerEvent(element, 'focus', false); - - var wasChecked = element.checked; - - // Set a flag that records if the page will unload - this isn't always accurate, because - // triggers the onbeforeunload event, even thought the page won't unload - var pageUnloading = false; - var pageUnloadDetector = function() { - pageUnloading = true; - }; - win.attachEvent("onbeforeunload", pageUnloadDetector); - this._modifyElementTarget(element); - if (element[eventType]) { - element[eventType](); - } - else { - this.browserbot.triggerMouseEvent(element, eventType, true, clientX, clientY); - } - - - // If the page is going to unload - still attempt to fire any subsequent events. - // However, we can't guarantee that the page won't unload half way through, so we need to handle exceptions. - try { - win.detachEvent("onbeforeunload", pageUnloadDetector); - - if (this._windowClosed(win)) { - return; - } - - // Onchange event is not triggered automatically in IE. - if (isDefined(element.checked) && wasChecked != element.checked) { - triggerEvent(element, 'change', true); - } - - } - catch (e) { - // If the page is unloading, we may get a "Permission denied" or "Unspecified error". - // Just ignore it, because the document may have unloaded. - if (pageUnloading) { - LOG.logHook = function() { - }; - LOG.warn("Caught exception when firing events on unloading page: " + e.message); - return; - } - throw e; - } -}; diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserdetect.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserdetect.js deleted file mode 100644 index 825521f0..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserdetect.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// Although it's generally better web development practice not to use -// browser-detection (feature detection is better), the subtle browser -// differences that Selenium has to work around seem to make it -// necessary. Maybe as we learn more about what we need, we can do this in -// a more "feature-centric" rather than "browser-centric" way. - -var BrowserVersion = function() { - this.name = navigator.appName; - - if (navigator.userAgent.indexOf('Mac OS X') != -1) { - this.isOSX = true; - } - - if (navigator.userAgent.indexOf('Windows NT 6') != -1) { - this.isVista = true; - } - - if (window.opera != null) { - this.browser = BrowserVersion.OPERA; - this.isOpera = true; - return; - } - - var _getQueryParameter = function(searchKey) { - var str = location.search.substr(1); - if (str == null) return null; - var clauses = str.split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=', 2); - var key = unescape(keyValuePair[0]); - if (key == searchKey) { - return unescape(keyValuePair[1]); - } - } - return null; - }; - - var self = this; - - var checkChrome = function() { - var loc = window.document.location.href; - try { - loc = window.top.document.location.href; - if (/^chrome:\/\//.test(loc)) { - self.isChrome = true; - } else { - self.isChrome = false; - } - } catch (e) { - // can't see the top (that means we might be chrome, but it's impossible to be sure) - self.isChromeDetectable = "no, top location couldn't be read in this window"; - if (_getQueryParameter('thisIsChrome')) { - self.isChrome = true; - } else { - self.isChrome = false; - } - } - - - } - - - - if (this.name == "Microsoft Internet Explorer") { - this.browser = BrowserVersion.IE; - this.isIE = true; - try { - if (window.top.SeleniumHTARunner && window.top.document.location.pathname.match(/.hta$/i)) { - this.isHTA = true; - } - } catch (e) { - this.isHTADetectable = "no, top location couldn't be read in this window"; - if (_getQueryParameter('thisIsHTA')) { - self.isHTA = true; - } else { - self.isHTA = false; - } - } - if (navigator.appVersion.match(/MSIE 6.0/)) { - this.isIE6 = true; - } - if ("0" == navigator.appMinorVersion) { - this.preSV1 = true; - if (this.isIE6) { - this.appearsToBeBrokenInitialIE6 = true; - } - } - return; - } - - if (navigator.userAgent.indexOf('Safari') != -1) { - this.browser = BrowserVersion.SAFARI; - this.isSafari = true; - this.khtml = true; - return; - } - - if (navigator.userAgent.indexOf('Konqueror') != -1) { - this.browser = BrowserVersion.KONQUEROR; - this.isKonqueror = true; - this.khtml = true; - return; - } - - if (navigator.userAgent.indexOf('Firefox') != -1) { - this.browser = BrowserVersion.FIREFOX; - this.isFirefox = true; - this.isGecko = true; - var result = /.*Firefox\/([\d\.]+).*/.exec(navigator.userAgent); - if (result) { - this.firefoxVersion = result[1]; - } - checkChrome(); - return; - } - - if (navigator.userAgent.indexOf('Gecko') != -1) { - this.browser = BrowserVersion.MOZILLA; - this.isMozilla = true; - this.isGecko = true; - checkChrome(); - return; - } - - this.browser = BrowserVersion.UNKNOWN; -} - -BrowserVersion.OPERA = "Opera"; -BrowserVersion.IE = "IE"; -BrowserVersion.KONQUEROR = "Konqueror"; -BrowserVersion.SAFARI = "Safari"; -BrowserVersion.FIREFOX = "Firefox"; -BrowserVersion.MOZILLA = "Mozilla"; -BrowserVersion.UNKNOWN = "Unknown"; - -var browserVersion = new BrowserVersion(); diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-commandhandlers.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-commandhandlers.js deleted file mode 100644 index c893b675..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-commandhandlers.js +++ /dev/null @@ -1,377 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -// A naming convention used in this file: -// -// -// - a "seleniumApi" is an instance of the Selenium object, defined in selenium-api.js. -// -// - a "Method" is an unbound function whose target must be supplied when it's called, ie. -// it should be invoked using Function.call() or Function.apply() -// -// - a "Block" is a function that has been bound to a target object, so can be called invoked directly -// (or with a null target) -// -// - "CommandHandler" is effectively an abstract base for -// various handlers including ActionHandler, AccessorHandler and AssertHandler. -// Subclasses need to implement an execute(seleniumApi, command) function, -// where seleniumApi is the Selenium object, and command a SeleniumCommand object. -// -// - Handlers will return a "result" object (ActionResult, AccessorResult, AssertResult). -// ActionResults may contain a .terminationCondition function which is run by -// -executionloop.js after the command is run; we'll run it over and over again -// until it returns true or the .terminationCondition throws an exception. -// AccessorResults will contain the results of running getter (e.g. getTitle returns -// the title as a string). - -var CommandHandlerFactory = classCreate(); -objectExtend(CommandHandlerFactory.prototype, { - - initialize: function() { - this.handlers = {}; - }, - - registerAction: function(name, actionBlock, wait, dontCheckAlertsAndConfirms) { - this.handlers[name] = new ActionHandler(actionBlock, wait, dontCheckAlertsAndConfirms); - }, - - registerAccessor: function(name, accessBlock) { - this.handlers[name] = new AccessorHandler(accessBlock); - }, - - registerAssert: function(name, assertBlock, haltOnFailure) { - this.handlers[name] = new AssertHandler(assertBlock, haltOnFailure); - }, - - getCommandHandler: function(name) { - return this.handlers[name]; - }, - - _registerAllAccessors: function(seleniumApi) { - // Methods of the form getFoo(target) result in commands: - // getFoo, assertFoo, verifyFoo, assertNotFoo, verifyNotFoo - // storeFoo, waitForFoo, and waitForNotFoo. - for (var functionName in seleniumApi) { - var match = /^(get|is)([A-Z].+)$/.exec(functionName); - if (match) { - var accessMethod = seleniumApi[functionName]; - var accessBlock = fnBind(accessMethod, seleniumApi); - var baseName = match[2]; - var isBoolean = (match[1] == "is"); - var requiresTarget = (accessMethod.length == 1); - - this.registerAccessor(functionName, accessBlock); - this._registerStoreCommandForAccessor(baseName, accessBlock, requiresTarget); - - var predicateBlock = this._predicateForAccessor(accessBlock, requiresTarget, isBoolean); - this._registerAssertionsForPredicate(baseName, predicateBlock); - this._registerWaitForCommandsForPredicate(seleniumApi, baseName, predicateBlock); - } - } - }, - - _registerAllActions: function(seleniumApi) { - for (var functionName in seleniumApi) { - var match = /^do([A-Z].+)$/.exec(functionName); - if (match) { - var actionName = match[1].lcfirst(); - var actionMethod = seleniumApi[functionName]; - var dontCheckPopups = actionMethod.dontCheckAlertsAndConfirms; - var actionBlock = fnBind(actionMethod, seleniumApi); - this.registerAction(actionName, actionBlock, false, dontCheckPopups); - this.registerAction(actionName + "AndWait", actionBlock, true, dontCheckPopups); - } - } - }, - - _registerAllAsserts: function(seleniumApi) { - for (var functionName in seleniumApi) { - var match = /^assert([A-Z].+)$/.exec(functionName); - if (match) { - var assertBlock = fnBind(seleniumApi[functionName], seleniumApi); - - // Register the assert with the "assert" prefix, and halt on failure. - var assertName = functionName; - this.registerAssert(assertName, assertBlock, true); - - // Register the assert with the "verify" prefix, and do not halt on failure. - var verifyName = "verify" + match[1]; - this.registerAssert(verifyName, assertBlock, false); - } - } - }, - - registerAll: function(seleniumApi) { - this._registerAllAccessors(seleniumApi); - this._registerAllActions(seleniumApi); - this._registerAllAsserts(seleniumApi); - }, - - _predicateForAccessor: function(accessBlock, requiresTarget, isBoolean) { - if (isBoolean) { - return this._predicateForBooleanAccessor(accessBlock); - } - if (requiresTarget) { - return this._predicateForSingleArgAccessor(accessBlock); - } - return this._predicateForNoArgAccessor(accessBlock); - }, - - _predicateForSingleArgAccessor: function(accessBlock) { - // Given an accessor function getBlah(target), - // return a "predicate" equivalient to isBlah(target, value) that - // is true when the value returned by the accessor matches the specified value. - return function(target, value) { - var accessorResult = accessBlock(target); - accessorResult = selArrayToString(accessorResult); - if (PatternMatcher.matches(value, accessorResult)) { - return new PredicateResult(true, "Actual value '" + accessorResult + "' did match '" + value + "'"); - } else { - return new PredicateResult(false, "Actual value '" + accessorResult + "' did not match '" + value + "'"); - } - }; - }, - - _predicateForNoArgAccessor: function(accessBlock) { - // Given a (no-arg) accessor function getBlah(), - // return a "predicate" equivalient to isBlah(value) that - // is true when the value returned by the accessor matches the specified value. - return function(value) { - var accessorResult = accessBlock(); - accessorResult = selArrayToString(accessorResult); - if (PatternMatcher.matches(value, accessorResult)) { - return new PredicateResult(true, "Actual value '" + accessorResult + "' did match '" + value + "'"); - } else { - return new PredicateResult(false, "Actual value '" + accessorResult + "' did not match '" + value + "'"); - } - }; - }, - - _predicateForBooleanAccessor: function(accessBlock) { - // Given a boolean accessor function isBlah(), - // return a "predicate" equivalient to isBlah() that - // returns an appropriate PredicateResult value. - return function() { - var accessorResult; - if (arguments.length > 2) throw new SeleniumError("Too many arguments! " + arguments.length); - if (arguments.length == 2) { - accessorResult = accessBlock(arguments[0], arguments[1]); - } else if (arguments.length == 1) { - accessorResult = accessBlock(arguments[0]); - } else { - accessorResult = accessBlock(); - } - if (accessorResult) { - return new PredicateResult(true, "true"); - } else { - return new PredicateResult(false, "false"); - } - }; - }, - - _invertPredicate: function(predicateBlock) { - // Given a predicate, return the negation of that predicate. - // Leaves the message unchanged. - // Used to create assertNot, verifyNot, and waitForNot commands. - return function(target, value) { - var result = predicateBlock(target, value); - result.isTrue = !result.isTrue; - return result; - }; - }, - - createAssertionFromPredicate: function(predicateBlock) { - // Convert an isBlahBlah(target, value) function into an assertBlahBlah(target, value) function. - return function(target, value) { - var result = predicateBlock(target, value); - if (!result.isTrue) { - Assert.fail(result.message); - } - }; - }, - - _invertPredicateName: function(baseName) { - var matchResult = /^(.*)Present$/.exec(baseName); - if (matchResult != null) { - return matchResult[1] + "NotPresent"; - } - return "Not" + baseName; - }, - - _registerAssertionsForPredicate: function(baseName, predicateBlock) { - // Register an assertion, a verification, a negative assertion, - // and a negative verification based on the specified accessor. - var assertBlock = this.createAssertionFromPredicate(predicateBlock); - this.registerAssert("assert" + baseName, assertBlock, true); - this.registerAssert("verify" + baseName, assertBlock, false); - - var invertedPredicateBlock = this._invertPredicate(predicateBlock); - var negativeassertBlock = this.createAssertionFromPredicate(invertedPredicateBlock); - this.registerAssert("assert" + this._invertPredicateName(baseName), negativeassertBlock, true); - this.registerAssert("verify" + this._invertPredicateName(baseName), negativeassertBlock, false); - }, - - _waitForActionForPredicate: function(predicateBlock) { - // Convert an isBlahBlah(target, value) function into a waitForBlahBlah(target, value) function. - return function(target, value) { - var terminationCondition = function () { - try { - return predicateBlock(target, value).isTrue; - } catch (e) { - // Treat exceptions as meaning the condition is not yet met. - // Useful, for example, for waitForValue when the element has - // not even been created yet. - // TODO: possibly should rethrow some types of exception. - return false; - } - }; - return Selenium.decorateFunctionWithTimeout(terminationCondition, this.defaultTimeout); - }; - }, - - _registerWaitForCommandsForPredicate: function(seleniumApi, baseName, predicateBlock) { - // Register a waitForBlahBlah and waitForNotBlahBlah based on the specified accessor. - var waitForActionMethod = this._waitForActionForPredicate(predicateBlock); - var waitForActionBlock = fnBind(waitForActionMethod, seleniumApi); - - var invertedPredicateBlock = this._invertPredicate(predicateBlock); - var waitForNotActionMethod = this._waitForActionForPredicate(invertedPredicateBlock); - var waitForNotActionBlock = fnBind(waitForNotActionMethod, seleniumApi); - - this.registerAction("waitFor" + baseName, waitForActionBlock, false, true); - this.registerAction("waitFor" + this._invertPredicateName(baseName), waitForNotActionBlock, false, true); - //TODO decide remove "waitForNot.*Present" action name or not - //for the back compatiblity issues we still make waitForNot.*Present availble - this.registerAction("waitForNot" + baseName, waitForNotActionBlock, false, true); - }, - - _registerStoreCommandForAccessor: function(baseName, accessBlock, requiresTarget) { - var action; - if (requiresTarget) { - action = function(target, varName) { - storedVars[varName] = accessBlock(target); - }; - } else { - action = function(varName) { - storedVars[varName] = accessBlock(); - }; - } - this.registerAction("store" + baseName, action, false, true); - } - -}); - -function PredicateResult(isTrue, message) { - this.isTrue = isTrue; - this.message = message; -} - -// NOTE: The CommandHandler is effectively an abstract base for -// various handlers including ActionHandler, AccessorHandler and AssertHandler. -// Subclasses need to implement an execute(seleniumApi, command) function, -// where seleniumApi is the Selenium object, and command a SeleniumCommand object. -function CommandHandler(type, haltOnFailure) { - this.type = type; - this.haltOnFailure = haltOnFailure; -} - -// An ActionHandler is a command handler that executes the sepcified action, -// possibly checking for alerts and confirmations (if checkAlerts is set), and -// possibly waiting for a page load if wait is set. -function ActionHandler(actionBlock, wait, dontCheckAlerts) { - this.actionBlock = actionBlock; - CommandHandler.call(this, "action", true); - if (wait) { - this.wait = true; - } - // note that dontCheckAlerts could be undefined!!! - this.checkAlerts = (dontCheckAlerts) ? false : true; -} -ActionHandler.prototype = new CommandHandler; -ActionHandler.prototype.execute = function(seleniumApi, command) { - if (this.checkAlerts && (null == /(Alert|Confirmation)(Not)?Present/.exec(command.command))) { - // todo: this conditional logic is ugly - seleniumApi.ensureNoUnhandledPopups(); - } - var terminationCondition = this.actionBlock(command.target, command.value); - // If the handler didn't return a wait flag, check to see if the - // handler was registered with the wait flag. - if (terminationCondition == undefined && this.wait) { - terminationCondition = seleniumApi.makePageLoadCondition(); - } - return new ActionResult(terminationCondition); -}; - -function ActionResult(terminationCondition) { - this.terminationCondition = terminationCondition; -} - -function AccessorHandler(accessBlock) { - this.accessBlock = accessBlock; - CommandHandler.call(this, "accessor", true); -} -AccessorHandler.prototype = new CommandHandler; -AccessorHandler.prototype.execute = function(seleniumApi, command) { - var returnValue = this.accessBlock(command.target, command.value); - return new AccessorResult(returnValue); -}; - -function AccessorResult(result) { - this.result = result; -} - -/** - * Handler for assertions and verifications. - */ -function AssertHandler(assertBlock, haltOnFailure) { - this.assertBlock = assertBlock; - CommandHandler.call(this, "assert", haltOnFailure || false); -} -AssertHandler.prototype = new CommandHandler; -AssertHandler.prototype.execute = function(seleniumApi, command) { - var result = new AssertResult(); - try { - this.assertBlock(command.target, command.value); - } catch (e) { - // If this is not a AssertionFailedError, or we should haltOnFailure, rethrow. - if (!e.isAssertionFailedError) { - throw e; - } - if (this.haltOnFailure) { - var error = new SeleniumError(e.failureMessage); - throw error; - } - result.setFailed(e.failureMessage); - } - return result; -}; - -function AssertResult() { - this.passed = true; -} -AssertResult.prototype.setFailed = function(message) { - this.passed = null; - this.failed = true; - this.failureMessage = message; -} - -function SeleniumCommand(command, target, value, isBreakpoint) { - this.command = command; - this.target = target; - this.value = value; - this.isBreakpoint = isBreakpoint; -} - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-executionloop.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-executionloop.js deleted file mode 100644 index 39fa2421..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-executionloop.js +++ /dev/null @@ -1,175 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -function TestLoop(commandFactory) { - this.commandFactory = commandFactory; -} - -TestLoop.prototype = { - - start : function() { - selenium.reset(); - LOG.debug("currentTest.start()"); - this.continueTest(); - }, - - continueTest : function() { - /** - * Select the next command and continue the test. - */ - LOG.debug("currentTest.continueTest() - acquire the next command"); - if (! this.aborted) { - this.currentCommand = this.nextCommand(); - } - if (! this.requiresCallBack) { - this.continueTestAtCurrentCommand(); - } // otherwise, just finish and let the callback invoke continueTestAtCurrentCommand() - }, - - continueTestAtCurrentCommand : function() { - LOG.debug("currentTest.continueTestAtCurrentCommand()"); - if (this.currentCommand) { - // TODO: rename commandStarted to commandSelected, OR roll it into nextCommand - this.commandStarted(this.currentCommand); - this._resumeAfterDelay(); - } else { - this._testComplete(); - } - }, - - _resumeAfterDelay : function() { - /** - * Pause, then execute the current command. - */ - - // Get the command delay. If a pauseInterval is set, use it once - // and reset it. Otherwise, use the defined command-interval. - var delay = this.pauseInterval || this.getCommandInterval(); - this.pauseInterval = undefined; - - if (this.currentCommand.isBreakpoint || delay < 0) { - // Pause: enable the "next/continue" button - this.pause(); - } else { - window.setTimeout(fnBind(this.resume, this), delay); - } - }, - - resume: function() { - /** - * Select the next command and continue the test. - */ - LOG.debug("currentTest.resume() - actually execute"); - try { - selenium.browserbot.runScheduledPollers(); - this._executeCurrentCommand(); - this.continueTestWhenConditionIsTrue(); - } catch (e) { - if (!this._handleCommandError(e)) { - this.testComplete(); - } else { - this.continueTest(); - } - } - }, - - _testComplete : function() { - selenium.ensureNoUnhandledPopups(); - this.testComplete(); - }, - - _executeCurrentCommand : function() { - /** - * Execute the current command. - * - * @return a function which will be used to determine when - * execution can continue, or null if we can continue immediately - */ - var command = this.currentCommand; - LOG.info("Executing: |" + command.command + " | " + command.target + " | " + command.value + " |"); - - var handler = this.commandFactory.getCommandHandler(command.command); - if (handler == null) { - throw new SeleniumError("Unknown command: '" + command.command + "'"); - } - - command.target = selenium.preprocessParameter(command.target); - command.value = selenium.preprocessParameter(command.value); - LOG.debug("Command found, going to execute " + command.command); - this.result = handler.execute(selenium, command); - - - this.waitForCondition = this.result.terminationCondition; - - }, - - _handleCommandError : function(e) { - if (!e.isSeleniumError) { - LOG.exception(e); - var msg = "Command execution failure. Please search the forum at http://clearspace.openqa.org for error details from the log window."; - msg += " The error message is: " + extractExceptionMessage(e); - return this.commandError(msg); - } else { - LOG.error(e.message); - return this.commandError(e.message); - } - }, - - continueTestWhenConditionIsTrue: function () { - /** - * Busy wait for waitForCondition() to become true, and then carry - * on with test. Fail the current test if there's a timeout or an - * exception. - */ - //LOG.debug("currentTest.continueTestWhenConditionIsTrue()"); - selenium.browserbot.runScheduledPollers(); - try { - if (this.waitForCondition == null) { - LOG.debug("null condition; let's continueTest()"); - LOG.debug("Command complete"); - this.commandComplete(this.result); - this.continueTest(); - } else if (this.waitForCondition()) { - LOG.debug("condition satisfied; let's continueTest()"); - this.waitForCondition = null; - LOG.debug("Command complete"); - this.commandComplete(this.result); - this.continueTest(); - } else { - //LOG.debug("waitForCondition was false; keep waiting!"); - window.setTimeout(fnBind(this.continueTestWhenConditionIsTrue, this), 10); - } - } catch (e) { - this.result = {}; - this.result.failed = true; - this.result.failureMessage = extractExceptionMessage(e); - this.commandComplete(this.result); - this.continueTest(); - } - }, - - pause : function() {}, - nextCommand : function() {}, - commandStarted : function() {}, - commandComplete : function() {}, - commandError : function() {}, - testComplete : function() {}, - - getCommandInterval : function() { - return 0; - } - -} diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-logging.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-logging.js deleted file mode 100644 index eac9d2a7..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-logging.js +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var Logger = function() { - this.logWindow = null; -} -Logger.prototype = { - - logLevels: { - debug: 0, - info: 1, - warn: 2, - error: 3, - off: 999 - }, - - pendingMessages: new Array(), - - threshold: "info", - - setLogLevelThreshold: function(logLevel) { - this.threshold = logLevel; - var logWindow = this.getLogWindow() - if (logWindow && logWindow.setThresholdLevel) { - logWindow.setThresholdLevel(logLevel); - } - // NOTE: log messages will be discarded until the log window is - // fully loaded. - }, - - getLogWindow: function() { - if (this.logWindow && this.logWindow.closed) { - this.logWindow = null; - } - return this.logWindow; - }, - - openLogWindow: function() { - this.logWindow = window.open( - getDocumentBase(document) + "SeleniumLog.html?startingThreshold="+this.threshold, "SeleniumLog", - "width=600,height=1000,bottom=0,right=0,status,scrollbars,resizable" - ); - this.logWindow.moveTo(window.screenX + 1210, window.screenY + window.outerHeight - 1400); - if (browserVersion.appearsToBeBrokenInitialIE6) { - // I would really prefer for the message to immediately appear in the log window, the instant the user requests that the log window be - // visible. But when I initially coded it this way, thou message simply didn't appear unless I stepped through the code with a debugger. - // So obviously there is some timing issue here which I don't have the patience to figure out. - var pendingMessage = new LogMessage("warn", "You appear to be running an unpatched IE 6, which is not stable and can crash due to memory problems. We recommend you run Windows update to install a more stable version of IE."); - this.pendingMessages.push(pendingMessage); - } - return this.logWindow; - }, - - show: function() { - if (! this.getLogWindow()) { - this.openLogWindow(); - } - setTimeout(function(){LOG.error("Log window displayed. Logging events will now be recorded to this window.");}, 500); - }, - - logHook: function(logLevel, message) { - }, - - log: function(logLevel, message) { - if (this.logLevels[logLevel] < this.logLevels[this.threshold]) { - return; - } - this.logHook(logLevel, message); - var logWindow = this.getLogWindow(); - if (logWindow) { - if (logWindow.append) { - if (logWindow.disabled) { - logWindow.callBack = fnBind(this.setLogLevelThreshold, this); - logWindow.enableButtons(); - } - if (this.pendingMessages.length > 0) { - logWindow.append("info("+(new Date().getTime())+"): Appending missed logging messages", "info"); - while (this.pendingMessages.length > 0) { - var msg = this.pendingMessages.shift(); - logWindow.append(msg.type + "("+msg.timestamp+"): " + msg.msg, msg.type); - } - logWindow.append("info("+(new Date().getTime())+"): Done appending missed logging messages", "info"); - } - logWindow.append(logLevel + "("+(new Date().getTime())+"): " + message, logLevel); - } - } else { - // TODO these logging messages are never flushed, which creates - // an enormous array of strings that never stops growing. - // there should at least be a way to clear the messages! - this.pendingMessages.push(new LogMessage(logLevel, message)); - } - }, - - close: function(message) { - if (this.logWindow != null) { - try { - this.logWindow.close(); - } catch (e) { - // swallow exception - // the window is probably closed if we get an exception here - } - this.logWindow = null; - } - }, - - debug: function(message) { - this.log("debug", message); - }, - - info: function(message) { - this.log("info", message); - }, - - warn: function(message) { - this.log("warn", message); - }, - - error: function(message) { - this.log("error", message); - }, - - exception: function(exception) { - this.error("Unexpected Exception: " + extractExceptionMessage(exception)); - this.error("Exception details: " + describe(exception, ', ')); - } - -}; - -var LOG = new Logger(); - -var LogMessage = function(type, msg) { - this.type = type; - this.msg = msg; - this.timestamp = (new Date().getTime()); -} diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-remoterunner.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-remoterunner.js deleted file mode 100644 index 70ed3282..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-remoterunner.js +++ /dev/null @@ -1,695 +0,0 @@ -/* -* Copyright 2005 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -passColor = "#cfffcf"; -failColor = "#ffcfcf"; -errorColor = "#ffffff"; -workingColor = "#DEE7EC"; -doneColor = "#FFFFCC"; - -var injectedSessionId; - -var postResult = "START"; -var debugMode = false; -var relayToRC = null; -var proxyInjectionMode = false; -var uniqueId = 'sel_' + Math.round(100000 * Math.random()); -var seleniumSequenceNumber = 0; -var cmd8 = ""; -var cmd7 = ""; -var cmd6 = ""; -var cmd5 = ""; -var cmd4 = ""; -var cmd3 = ""; -var cmd2 = ""; -var cmd1 = ""; -var lastCmd = ""; -var lastCmdTime = new Date(); - -var RemoteRunnerOptions = classCreate(); -objectExtend(RemoteRunnerOptions.prototype, URLConfiguration.prototype); -objectExtend(RemoteRunnerOptions.prototype, { - initialize: function() { - this._acquireQueryString(); - }, - isDebugMode: function() { - return this._isQueryParameterTrue("debugMode"); - }, - - getContinue: function() { - return this._getQueryParameter("continue"); - }, - - getDriverUrl: function() { - return this._getQueryParameter("driverUrl"); - }, - - // requires per-session extension Javascript as soon as this Selenium - // instance becomes aware of the session identifier - getSessionId: function() { - var sessionId = this._getQueryParameter("sessionId"); - requireExtensionJs(sessionId); - return sessionId; - }, - - _acquireQueryString: function () { - if (this.queryString) return; - if (browserVersion.isHTA) { - var args = this._extractArgs(); - if (args.length < 2) return null; - this.queryString = args[1]; - } else if (proxyInjectionMode) { - this.queryString = window.location.search.substr(1); - } else { - this.queryString = top.location.search.substr(1); - } - } - -}); -var runOptions; - -function runSeleniumTest() { - runOptions = new RemoteRunnerOptions(); - var testAppWindow; - - if (runOptions.isMultiWindowMode()) { - testAppWindow = openSeparateApplicationWindow('Blank.html', true); - } else if (sel$('selenium_myiframe') != null) { - var myiframe = sel$('selenium_myiframe'); - if (myiframe) { - testAppWindow = myiframe.contentWindow; - } - } - else { - proxyInjectionMode = true; - testAppWindow = window; - } - selenium = Selenium.createForWindow(testAppWindow, proxyInjectionMode); - if (runOptions.getBaseUrl()) { - selenium.browserbot.baseUrl = runOptions.getBaseUrl(); - } - if (!debugMode) { - debugMode = runOptions.isDebugMode(); - } - if (proxyInjectionMode) { - LOG.logHook = logToRc; - selenium.browserbot._modifyWindow(testAppWindow); - } - else if (debugMode) { - LOG.logHook = logToRc; - } - window.selenium = selenium; - - commandFactory = new CommandHandlerFactory(); - commandFactory.registerAll(selenium); - - currentTest = new RemoteRunner(commandFactory); - - var doContinue = runOptions.getContinue(); - if (doContinue != null) postResult = "OK"; - - currentTest.start(); -} - -function buildDriverUrl() { - var driverUrl = runOptions.getDriverUrl(); - if (driverUrl != null) { - return driverUrl; - } - var s = window.location.href - var slashPairOffset = s.indexOf("//") + "//".length - var pathSlashOffset = s.substring(slashPairOffset).indexOf("/") - return s.substring(0, slashPairOffset + pathSlashOffset) + "/selenium-server/driver/"; - //return "http://localhost" + uniqueId + "/selenium-server/driver/"; -} - -function logToRc(logLevel, message) { - if (debugMode) { - if (logLevel == null) { - logLevel = "debug"; - } - sendToRCAndForget("logLevel=" + logLevel + ":" + message.replace(/[\n\r\015]/g, " ") + "\n", "logging=true"); - } -} - -function serializeString(name, s) { - return name + "=unescape(\"" + escape(s) + "\");"; -} - -function serializeObject(name, x) -{ - var s = ''; - - if (isArray(x)) - { - s = name + "=new Array(); "; - var len = x["length"]; - for (var j = 0; j < len; j++) - { - s += serializeString(name + "[" + j + "]", x[j]); - } - } - else if (typeof x == "string") - { - s = serializeString(name, x); - } - else - { - throw "unrecognized object not encoded: " + name + "(" + x + ")"; - } - return s; -} - -function relayBotToRC(s) { -} - -// seems like no one uses this, but in fact it is called using eval from server-side PI mode code; however, -// because multiple names can map to the same popup, assigning a single name confuses matters sometimes; -// thus, I'm disabling this for now. -Nelson 10/21/06 -function setSeleniumWindowName(seleniumWindowName) { -//selenium.browserbot.getCurrentWindow()['seleniumWindowName'] = seleniumWindowName; -} - -RemoteRunner = classCreate(); -objectExtend(RemoteRunner.prototype, new TestLoop()); -objectExtend(RemoteRunner.prototype, { - initialize : function(commandFactory) { - this.commandFactory = commandFactory; - this.requiresCallBack = true; - this.commandNode = null; - this.xmlHttpForCommandsAndResults = null; - }, - - nextCommand : function() { - var urlParms = ""; - if (postResult == "START") { - urlParms += "seleniumStart=true"; - } - this.xmlHttpForCommandsAndResults = XmlHttp.create(); - sendToRC(postResult, urlParms, fnBind(this._HandleHttpResponse, this), this.xmlHttpForCommandsAndResults); - }, - - commandStarted : function(command) { - this.commandNode = document.createElement("div"); - var cmdText = command.command + '('; - if (command.target != null && command.target != "") { - cmdText += command.target; - if (command.value != null && command.value != "") { - cmdText += ', ' + command.value; - } - } - if (cmdText.length > 70) { - cmdText = cmdText.substring(0, 70) + "...\n"; - } else { - cmdText += ")\n"; - } - - if (cmdText == lastCmd) { - var rightNow = new Date(); - var msSinceStart = rightNow.getTime() - lastCmdTime.getTime(); - var sinceStart = msSinceStart + "ms"; - if (msSinceStart > 1000) { - sinceStart = Math.round(msSinceStart / 1000) + "s"; - } - cmd1 = "Same command (" + sinceStart + "): " + lastCmd; - } else { - lastCmdTime = new Date(); - cmd8 = cmd7; - cmd7 = cmd6; - cmd6 = cmd5; - cmd5 = cmd4; - cmd4 = cmd3; - cmd3 = cmd2; - cmd2 = cmd1; - cmd1 = cmdText; - } - lastCmd = cmdText; - - if (! proxyInjectionMode) { - var commandList = document.commands.commandList; - commandList.value = cmd8 + cmd7 + cmd6 + cmd5 + cmd4 + cmd3 + cmd2 + cmd1; - commandList.scrollTop = commandList.scrollHeight; - } - }, - - commandComplete : function(result) { - - if (result.failed) { - if (postResult == "CONTINUATION") { - currentTest.aborted = true; - } - postResult = result.failureMessage; - this.commandNode.title = result.failureMessage; - this.commandNode.style.backgroundColor = failColor; - } else if (result.passed) { - postResult = "OK"; - this.commandNode.style.backgroundColor = passColor; - } else { - if (result.result == null) { - postResult = "OK"; - } else { - var actualResult = result.result; - actualResult = selArrayToString(actualResult); - postResult = "OK," + actualResult; - } - this.commandNode.style.backgroundColor = doneColor; - } - }, - - commandError : function(message) { - postResult = "ERROR: " + message; - this.commandNode.style.backgroundColor = errorColor; - this.commandNode.titcle = message; - }, - - testComplete : function() { - window.status = "Selenium Tests Complete, for this Test" - // Continue checking for new results - this.continueTest(); - postResult = "START"; - }, - - _HandleHttpResponse : function() { - // When request is completed - if (this.xmlHttpForCommandsAndResults.readyState == 4) { - // OK - if (this.xmlHttpForCommandsAndResults.status == 200) { - if (this.xmlHttpForCommandsAndResults.responseText=="") { - LOG.error("saw blank string xmlHttpForCommandsAndResults.responseText"); - return; - } - var command = this._extractCommand(this.xmlHttpForCommandsAndResults); - if (command.command == 'retryLast') { - setTimeout(fnBind(function() { - sendToRC("RETRY", "retry=true", fnBind(this._HandleHttpResponse, this), this.xmlHttpForCommandsAndResults, true); - }, this), 1000); - } else { - this.currentCommand = command; - this.continueTestAtCurrentCommand(); - } - } - // Not OK - else { - var s = 'xmlHttp returned: ' + this.xmlHttpForCommandsAndResults.status + ": " + this.xmlHttpForCommandsAndResults.statusText; - LOG.error(s); - this.currentCommand = null; - setTimeout(fnBind(this.continueTestAtCurrentCommand, this), 2000); - } - - } - }, - - _extractCommand : function(xmlHttp) { - var command, text, json; - text = command = xmlHttp.responseText; - if (/^json=/.test(text)) { - eval(text); - if (json.rest) { - eval(json.rest); - } - return json; - } - try { - var re = new RegExp("^(.*?)\n((.|[\r\n])*)"); - if (re.exec(xmlHttp.responseText)) { - command = RegExp.$1; - var rest = RegExp.$2; - rest = rest.trim(); - if (rest) { - eval(rest); - } - } - else { - command = xmlHttp.responseText; - } - } catch (e) { - alert('could not get responseText: ' + e.message); - } - if (command.substr(0, '|testComplete'.length) == '|testComplete') { - return null; - } - - return this._createCommandFromRequest(command); - }, - - - _delay : function(millis) { - var startMillis = new Date(); - while (true) { - milli = new Date(); - if (milli - startMillis > millis) { - break; - } - } - }, - -// Parses a URI query string into a SeleniumCommand object - _createCommandFromRequest : function(commandRequest) { - //decodeURIComponent doesn't strip plus signs - var processed = commandRequest.replace(/\+/g, "%20"); - // strip trailing spaces - var processed = processed.replace(/\s+$/, ""); - var vars = processed.split("&"); - var cmdArgs = new Object(); - for (var i = 0; i < vars.length; i++) { - var pair = vars[i].split("="); - cmdArgs[pair[0]] = pair[1]; - } - var cmd = cmdArgs['cmd']; - var arg1 = cmdArgs['1']; - if (null == arg1) arg1 = ""; - arg1 = decodeURIComponent(arg1); - var arg2 = cmdArgs['2']; - if (null == arg2) arg2 = ""; - arg2 = decodeURIComponent(arg2); - if (cmd == null) { - throw new Error("Bad command request: " + commandRequest); - } - return new SeleniumCommand(cmd, arg1, arg2); - } - -}) - - -function sendToRC(dataToBePosted, urlParms, callback, xmlHttpObject, async) { - if (async == null) { - async = true; - } - if (xmlHttpObject == null) { - xmlHttpObject = XmlHttp.create(); - } - var url = buildDriverUrl() + "?" - if (urlParms) { - url += urlParms; - } - url = addUrlParams(url); - url += "&sequenceNumber=" + seleniumSequenceNumber++; - - var postedData = "postedData=" + encodeURIComponent(dataToBePosted); - - //xmlHttpObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - xmlHttpObject.open("POST", url, async); - if (callback) xmlHttpObject.onreadystatechange = callback; - xmlHttpObject.send(postedData); - return null; -} - -function addUrlParams(url) { - return url + "&localFrameAddress=" + (proxyInjectionMode ? makeAddressToAUTFrame() : "top") - + getSeleniumWindowNameURLparameters() - + "&uniqueId=" + uniqueId - + buildDriverParams() + preventBrowserCaching() -} - -function sendToRCAndForget(dataToBePosted, urlParams) { - var url; - if (!(browserVersion.isChrome || browserVersion.isHTA)) { - // DGF we're behind a proxy, so we can send our logging message to literally any host, to avoid 2-connection limit - var protocol = "http:"; - if (window.location.protocol == "https:") { - // DGF if we're in HTTPS, use another HTTPS url to avoid security warning - protocol = "https:"; - } - // we don't choose a super large random value, but rather 1 - 16, because this matches with the pre-computed - // tunnels waiting on the Selenium Server side. This gives us higher throughput than the two-connection-per-host - // limitation, but doesn't require we generate an extremely large ammount of fake SSL certs either. - url = protocol + "//" + Math.floor(Math.random()* 16 + 1) + ".selenium.doesnotexist/selenium-server/driver/?" + urlParams; - } else { - url = buildDriverUrl() + "?" + urlParams; - } - url = addUrlParams(url); - - var method = "GET"; - if (method == "POST") { - // DGF submit a request using an iframe; we can't see the response, but we don't need to - // TODO not using this mechanism because it screws up back-button - var loggingForm = document.createElement("form"); - loggingForm.method = "POST"; - loggingForm.action = url; - loggingForm.target = "seleniumLoggingFrame"; - var postedDataInput = document.createElement("input"); - postedDataInput.type = "hidden"; - postedDataInput.name = "postedData"; - postedDataInput.value = dataToBePosted; - loggingForm.appendChild(postedDataInput); - document.body.appendChild(loggingForm); - loggingForm.submit(); - document.body.removeChild(loggingForm); - } else { - var postedData = "&postedData=" + encodeURIComponent(dataToBePosted); - var scriptTag = document.createElement("script"); - scriptTag.src = url + postedData; - document.body.appendChild(scriptTag); - document.body.removeChild(scriptTag); - } -} - -function buildDriverParams() { - var params = ""; - - var sessionId = runOptions.getSessionId(); - if (sessionId == undefined) { - sessionId = injectedSessionId; - } - if (sessionId != undefined) { - params = params + "&sessionId=" + sessionId; - } - return params; -} - -function preventBrowserCaching() { - var t = (new Date()).getTime(); - return "&counterToMakeURsUniqueAndSoStopPageCachingInTheBrowser=" + t; -} - -// -// Return URL parameters pertaining to the name(s?) of the current window -// -// In selenium, the main (i.e., first) window's name is a blank string. -// -// Additional pop-ups are associated with either 1.) the name given by the 2nd parameter to window.open, or 2.) the name of a -// property on the opening window which points at the window. -// -// An example of #2: if window X contains JavaScript as follows: -// -// var windowABC = window.open(...) -// -// Note that the example JavaScript above is equivalent to -// -// window["windowABC"] = window.open(...) -// -function getSeleniumWindowNameURLparameters() { - var w = (proxyInjectionMode ? selenium.browserbot.getCurrentWindow() : window).top; - var s = "&seleniumWindowName="; - if (w.opener == null) { - return s; - } - if (w["seleniumWindowName"] == null) { - if (w.name) { - w["seleniumWindowName"] = w.name; - } else { - w["seleniumWindowName"] = 'generatedSeleniumWindowName_' + Math.round(100000 * Math.random()); - } - } - s += w["seleniumWindowName"]; - var windowOpener = w.opener; - for (key in windowOpener) { - var val = null; - try { - val = windowOpener[key]; - } - catch(e) { - } - if (val==w) { - s += "&jsWindowNameVar=" + key; // found a js variable in the opener referring to this window - } - } - return s; -} - -// construct a JavaScript expression which leads to my frame (i.e., the frame containing the window -// in which this code is operating) -function makeAddressToAUTFrame(w, frameNavigationalJSexpression) -{ - if (w == null) - { - w = top; - frameNavigationalJSexpression = "top"; - } - - if (w == selenium.browserbot.getCurrentWindow()) - { - return frameNavigationalJSexpression; - } - for (var j = 0; j < w.frames.length; j++) - { - var t = makeAddressToAUTFrame(w.frames[j], frameNavigationalJSexpression + ".frames[" + j + "]"); - if (t != null) - { - return t; - } - } - return null; -} - -Selenium.prototype.doSetContext = function(context) { - /** - * Writes a message to the status bar and adds a note to the browser-side - * log. - * - * @param context - * the message to be sent to the browser - */ - //set the current test title - var ctx = document.getElementById("context"); - if (ctx != null) { - ctx.innerHTML = context; - } -}; - -/** - * Adds a script tag referencing a specially-named user extensions "file". The - * resource handler for this special file (which won't actually exist) will use - * the session ID embedded in its name to retrieve per-session specified user - * extension javascript. - * - * @param sessionId - */ -function requireExtensionJs(sessionId) { - var src = 'scripts/user-extensions.js[' + sessionId + ']'; - if (document.getElementById(src) == null) { - var scriptTag = document.createElement('script'); - scriptTag.language = 'JavaScript'; - scriptTag.type = 'text/javascript'; - scriptTag.src = src; - scriptTag.id = src; - var headTag = document.getElementsByTagName('head')[0]; - headTag.appendChild(scriptTag); - } -} - -Selenium.prototype.doAttachFile = function(fieldLocator,fileLocator) { - /** - * Sets a file input (upload) field to the file listed in fileLocator - * - * @param fieldLocator an element locator - * @param fileLocator a URL pointing to the specified file. Before the file - * can be set in the input field (fieldLocator), Selenium RC may need to transfer the file - * to the local machine before attaching the file in a web page form. This is common in selenium - * grid configurations where the RC server driving the browser is not the same - * machine that started the test. - * - * Supported Browsers: Firefox ("*chrome") only. - * - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doCaptureScreenshot = function(filename) { - /** - * Captures a PNG screenshot to the specified file. - * - * @param filename the absolute path to the file to be written, e.g. "c:\blah\screenshot.png" - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doCaptureScreenshotToString = function() { - /** - * Capture a PNG screenshot. It then returns the file as a base 64 encoded string. - * - * @return string The base 64 encoded string of the screen shot (PNG file) - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doCaptureEntirePageScreenshotToString = function(kwargs) { - /** - * Downloads a screenshot of the browser current window canvas to a - * based 64 encoded PNG file. The entire windows canvas is captured, - * including parts rendered outside of the current view port. - * - * Currently this only works in Mozilla and when running in chrome mode. - * - * @param kwargs A kwargs string that modifies the way the screenshot is captured. Example: "background=#CCFFDD". This may be useful to set for capturing screenshots of less-than-ideal layouts, for example where absolute positioning causes the calculation of the canvas dimension to fail and a black background is exposed (possibly obscuring black text). - * - * @return string The base 64 encoded string of the page screenshot (PNG file) - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doShutDownSeleniumServer = function(keycode) { - /** - * Kills the running Selenium Server and all browser sessions. After you run this command, you will no longer be able to send - * commands to the server; you can't remotely start the server once it has been stopped. Normally - * you should prefer to run the "stop" command, which terminates the current browser session, rather than - * shutting down the entire server. - * - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doRetrieveLastRemoteControlLogs = function() { - /** - * Retrieve the last messages logged on a specific remote control. Useful for error reports, especially - * when running multiple remote controls in a distributed environment. The maximum number of log messages - * that can be retrieve is configured on remote control startup. - * - * @return string The last N log messages as a multi-line string. - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doKeyDownNative = function(keycode) { - /** - * Simulates a user pressing a key (without releasing it yet) by sending a native operating system keystroke. - * This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing - * a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and - * metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular - * element, focus on the element first before running this command. - * - * @param keycode an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doKeyUpNative = function(keycode) { - /** - * Simulates a user releasing a key by sending a native operating system keystroke. - * This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing - * a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and - * metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular - * element, focus on the element first before running this command. - * - * @param keycode an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - -Selenium.prototype.doKeyPressNative = function(keycode) { - /** - * Simulates a user pressing and releasing a key by sending a native operating system keystroke. - * This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing - * a key on the keyboard. It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and - * metaKeyDown commands, and does not target any particular HTML element. To send a keystroke to a particular - * element, focus on the element first before running this command. - * - * @param keycode an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes! - */ - // This doesn't really do anything on the JS side; we let the Selenium Server take care of this for us! -}; - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-testrunner.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-testrunner.js deleted file mode 100644 index efb488f7..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-testrunner.js +++ /dev/null @@ -1,1362 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -// An object representing the current test, used external -var currentTest = null; // TODO: get rid of this global, which mirrors the htmlTestRunner.currentTest -var selenium = null; - -var htmlTestRunner; -var HtmlTestRunner = classCreate(); -objectExtend(HtmlTestRunner.prototype, { - initialize: function() { - this.metrics = new Metrics(); - this.controlPanel = new HtmlTestRunnerControlPanel(); - this.testFailed = false; - this.currentTest = null; - this.runAllTests = false; - this.appWindow = null; - // we use a timeout here to make sure the LOG has loaded first, so we can see _every_ error - setTimeout(fnBind(function() { - this.loadSuiteFrame(); - }, this), 500); - }, - - getTestSuite: function() { - return suiteFrame.getCurrentTestSuite(); - }, - - markFailed: function() { - this.testFailed = true; - this.getTestSuite().markFailed(); - }, - - loadSuiteFrame: function() { - var logLevel = this.controlPanel.getDefaultLogLevel(); - if (logLevel) { - LOG.setLogLevelThreshold(logLevel); - } - if (selenium == null) { - var appWindow = this._getApplicationWindow(); - try { appWindow.location; } - catch (e) { - // when reloading, we may be pointing at an old window (Perm Denied) - setTimeout(fnBind(function() { - this.loadSuiteFrame(); - }, this), 50); - return; - } - selenium = Selenium.createForWindow(appWindow); - this._registerCommandHandlers(); - } - this.controlPanel.setHighlightOption(); - var testSuiteName = this.controlPanel.getTestSuiteName(); - var self = this; - if (testSuiteName) { - suiteFrame.load(testSuiteName, function() {setTimeout(fnBind(self._onloadTestSuite, self), 50)} ); - selenium.browserbot.baseUrl = absolutify(testSuiteName, window.location.href); - } - // DGF or should we use the old default? - // selenium.browserbot.baseUrl = window.location.href; - if (this.controlPanel.getBaseUrl()) { - selenium.browserbot.baseUrl = this.controlPanel.getBaseUrl(); - } - }, - - _getApplicationWindow: function () { - if (this.controlPanel.isMultiWindowMode()) { - return this._getSeparateApplicationWindow(); - } - return sel$('selenium_myiframe').contentWindow; - }, - - _getSeparateApplicationWindow: function () { - if (this.appWindow == null) { - this.appWindow = openSeparateApplicationWindow('TestRunner-splash.html', this.controlPanel.isAutomatedRun()); - } - return this.appWindow; - }, - - _onloadTestSuite:function () { - suiteFrame = new HtmlTestSuiteFrame(getSuiteFrame()); - if (! this.getTestSuite().isAvailable()) { - return; - } - if (this.controlPanel.isAutomatedRun()) { - this.startTestSuite(); - } else if (this.controlPanel.getAutoUrl()) { - //todo what is the autourl doing, left to check it out - addLoadListener(this._getApplicationWindow(), fnBind(this._startSingleTest, this)); - this._getApplicationWindow().src = this.controlPanel.getAutoUrl(); - } else { - var testCaseLoaded = fnBind(function(){this.testCaseLoaded=true;},this); - var testNumber = 0; - if (this.controlPanel.getTestNumber() != null){ - var testNumber = this.controlPanel.getTestNumber() - 1; - } - this.getTestSuite().getSuiteRows()[testNumber].loadTestCase(testCaseLoaded); - } - }, - - _startSingleTest:function () { - removeLoadListener(getApplicationWindow(), fnBind(this._startSingleTest, this)); - var singleTestName = this.controlPanel.getSingleTestName(); - testFrame.load(singleTestName, fnBind(this.startTest, this)); - }, - - _registerCommandHandlers: function () { - this.commandFactory = new CommandHandlerFactory(); - this.commandFactory.registerAll(selenium); - }, - - startTestSuite: function() { - this.controlPanel.reset(); - this.metrics.resetMetrics(); - this.getTestSuite().reset(); - this.runAllTests = true; - this.runNextTest(); - }, - - runNextTest: function () { - this.getTestSuite().updateSuiteWithResultOfPreviousTest(); - if (!this.runAllTests) { - return; - } - this.getTestSuite().runNextTestInSuite(); - }, - - startTest: function () { - this.controlPanel.reset(); - testFrame.scrollToTop(); - //todo: move testFailed and storedVars to TestCase - this.testFailed = false; - storedVars = new Object(); - storedVars.nbsp = String.fromCharCode(160); - storedVars.space = ' '; - this.currentTest = new HtmlRunnerTestLoop(testFrame.getCurrentTestCase(), this.metrics, this.commandFactory); - currentTest = this.currentTest; - this.currentTest.start(); - }, - - runSingleTest:function() { - this.runAllTests = false; - this.metrics.resetMetrics(); - this.startTest(); - } -}); - -var runInterval = 0; - -/** SeleniumFrame encapsulates an iframe element */ -var SeleniumFrame = classCreate(); -objectExtend(SeleniumFrame.prototype, { - - initialize : function(frame) { - this.frame = frame; - addLoadListener(this.frame, fnBind(this._handleLoad, this)); - }, - - getWindow : function() { - return this.frame.contentWindow; - }, - - getDocument : function() { - return this.frame.contentWindow.document; - }, - - _handleLoad: function() { - this._attachStylesheet(); - this._onLoad(); - if (this.loadCallback) { - this.loadCallback(); - } - }, - - _attachStylesheet: function() { - var d = this.getDocument(); - var head = d.getElementsByTagName('head').item(0); - var styleLink = d.createElement("link"); - styleLink.rel = "stylesheet"; - styleLink.type = "text/css"; - if (browserVersion && browserVersion.isChrome) { - // DGF We have to play a clever trick to get the right absolute path. - // This trick works on most browsers, (not IE), but is only needed in - // chrome - var tempLink = window.document.createElement("link"); - tempLink.href = "selenium-test.css"; // this will become an absolute href - styleLink.href = tempLink.href; - } else { - // this works in every browser (except Firefox in chrome mode) - var styleSheetPath = window.location.pathname.replace(/[^\/\\]+$/, "selenium-test.css"); - if (browserVersion.isIE && window.location.protocol == "file:") { - styleSheetPath = "file:///" + styleSheetPath; - } - styleLink.href = styleSheetPath; - } - // DGF You're only going to see this log message if you set defaultLogLevel=debug - LOG.debug("styleLink.href="+styleLink.href); - head.appendChild(styleLink); - }, - - _onLoad: function() { - }, - - scrollToTop : function() { - this.frame.contentWindow.scrollTo(0, 0); - }, - - _setLocation: function(location) { - var isChrome = browserVersion.isChrome || false; - var isHTA = browserVersion.isHTA || false; - // DGF TODO multiWindow - location += (location.indexOf("?") == -1 ? "?" : "&"); - location += "thisIsChrome=" + isChrome + "&thisIsHTA=" + isHTA; - if (browserVersion.isSafari) { - // safari doesn't reload the page when the location equals to current location. - // hence, set the location to blank so that the page will reload automatically. - this.frame.src = "about:blank"; - this.frame.src = location; - } else { - this.frame.contentWindow.location.replace(location); - } - }, - - load: function(/* url, [callback] */) { - if (arguments.length > 1) { - this.loadCallback = arguments[1]; - - } - this._setLocation(arguments[0]); - } - -}); - -/** HtmlTestSuiteFrame - encapsulates the suite iframe element */ -var HtmlTestSuiteFrame = classCreate(); -objectExtend(HtmlTestSuiteFrame.prototype, SeleniumFrame.prototype); -objectExtend(HtmlTestSuiteFrame.prototype, { - - getCurrentTestSuite: function() { - if (!this.currentTestSuite) { - this.currentTestSuite = new HtmlTestSuite(this.getDocument()); - } - return this.currentTestSuite; - } - -}); - -/** HtmlTestFrame - encapsulates the test-case iframe element */ -var HtmlTestFrame = classCreate(); -objectExtend(HtmlTestFrame.prototype, SeleniumFrame.prototype); -objectExtend(HtmlTestFrame.prototype, { - - _onLoad: function() { - this.currentTestCase = new HtmlTestCase(this.getWindow(), htmlTestRunner.getTestSuite().getCurrentRow()); - }, - - getCurrentTestCase: function() { - return this.currentTestCase; - } - -}); - -function onSeleniumLoad() { - suiteFrame = new HtmlTestSuiteFrame(getSuiteFrame()); - testFrame = new HtmlTestFrame(getTestFrame()); - htmlTestRunner = new HtmlTestRunner(); -} - -var suiteFrame; -var testFrame; - -function getSuiteFrame() { - var f = sel$('testSuiteFrame'); - if (f == null) { - f = top; - // proxyInjection mode does not set selenium_myiframe - } - return f; -} - -function getTestFrame() { - var f = sel$('testFrame'); - if (f == null) { - f = top; - // proxyInjection mode does not set selenium_myiframe - } - return f; -} - -var HtmlTestRunnerControlPanel = classCreate(); -objectExtend(HtmlTestRunnerControlPanel.prototype, URLConfiguration.prototype); -objectExtend(HtmlTestRunnerControlPanel.prototype, { - initialize: function() { - this._acquireQueryString(); - - this.runInterval = 0; - - this.highlightOption = sel$('highlightOption'); - this.pauseButton = sel$('pauseTest'); - this.stepButton = sel$('stepTest'); - - this.highlightOption.onclick = fnBindAsEventListener((function() { - this.setHighlightOption(); - }), this); - this.pauseButton.onclick = fnBindAsEventListener(this.pauseCurrentTest, this); - this.stepButton.onclick = fnBindAsEventListener(this.stepCurrentTest, this); - - - this.speedController = new Control.Slider('speedHandle', 'speedTrack', { - range: $R(0, 1000), - onSlide: fnBindAsEventListener(this.setRunInterval, this), - onChange: fnBindAsEventListener(this.setRunInterval, this) - }); - - this._parseQueryParameter(); - }, - - setHighlightOption: function () { - var isHighlight = this.highlightOption.checked; - selenium.browserbot.setShouldHighlightElement(isHighlight); - }, - - _parseQueryParameter: function() { - var tempRunInterval = this._getQueryParameter("runInterval"); - if (tempRunInterval) { - this.setRunInterval(tempRunInterval); - } - this.highlightOption.checked = this._getQueryParameter("highlight"); - }, - - setRunInterval: function(runInterval) { - this.runInterval = runInterval; - }, - - setToPauseAtNextCommand: function() { - this.runInterval = -1; - }, - - pauseCurrentTest: function () { - this.setToPauseAtNextCommand(); - this._switchPauseButtonToContinue(); - }, - - continueCurrentTest: function () { - this.reset(); - currentTest.resume(); - }, - - reset: function() { - this.runInterval = this.speedController.value; - this._switchContinueButtonToPause(); - }, - - _switchContinueButtonToPause: function() { - this.pauseButton.className = "cssPauseTest"; - this.pauseButton.onclick = fnBindAsEventListener(this.pauseCurrentTest, this); - }, - - _switchPauseButtonToContinue: function() { - sel$('stepTest').disabled = false; - this.pauseButton.className = "cssContinueTest"; - this.pauseButton.onclick = fnBindAsEventListener(this.continueCurrentTest, this); - }, - - stepCurrentTest: function () { - this.setToPauseAtNextCommand(); - currentTest.resume(); - }, - - isAutomatedRun: function() { - return this._isQueryParameterTrue("auto"); - }, - - shouldSaveResultsToFile: function() { - return this._isQueryParameterTrue("save"); - }, - - closeAfterTests: function() { - return this._isQueryParameterTrue("close"); - }, - - getTestSuiteName: function() { - return this._getQueryParameter("test"); - }, - - getTestNumber: function() { - return this._getQueryParameter("testNumber"); - }, - - getSingleTestName: function() { - return this._getQueryParameter("singletest"); - }, - - getAutoUrl: function() { - return this._getQueryParameter("autoURL"); - }, - - getDefaultLogLevel: function() { - return this._getQueryParameter("defaultLogLevel"); - }, - - getResultsUrl: function() { - return this._getQueryParameter("resultsUrl"); - }, - - _acquireQueryString: function() { - if (this.queryString) return; - if (browserVersion.isHTA) { - var args = this._extractArgs(); - if (args.length < 2) return null; - this.queryString = args[1]; - } else { - this.queryString = location.search.substr(1); - } - } - -}); - -var AbstractResultAwareRow = classCreate(); -objectExtend(AbstractResultAwareRow.prototype, { - - initialize: function(trElement) { - this.trElement = trElement; - }, - - setStatus: function(status) { - this.unselect(); - this.trElement.className = this.trElement.className.replace(/status_[a-z]+/, ""); - if (status) { - addClassName(this.trElement, "status_" + status); - } - }, - - select: function() { - addClassName(this.trElement, "selected"); - safeScrollIntoView(this.trElement); - }, - - unselect: function() { - removeClassName(this.trElement, "selected"); - }, - - markPassed: function() { - this.setStatus("passed"); - }, - - markDone: function() { - this.setStatus("done"); - }, - - markFailed: function() { - this.setStatus("failed"); - } - -}); - -var TitleRow = classCreate(); -objectExtend(TitleRow.prototype, AbstractResultAwareRow.prototype); -objectExtend(TitleRow.prototype, { - - initialize: function(trElement) { - this.trElement = trElement; - trElement.className = "title"; - } - -}); - -var HtmlTestCaseRow = classCreate(); -objectExtend(HtmlTestCaseRow.prototype, AbstractResultAwareRow.prototype); -objectExtend(HtmlTestCaseRow.prototype, { - - getCommand: function () { - return new SeleniumCommand(getText(this.trElement.cells[0]), - getText(this.trElement.cells[1]), - getText(this.trElement.cells[2]), - this.isBreakpoint()); - }, - - markFailed: function(errorMsg) { - AbstractResultAwareRow.prototype.markFailed.call(this, errorMsg); - this.setMessage(errorMsg); - }, - - setMessage: function(message) { - setText(this.trElement.cells[2], message); - }, - - reset: function() { - this.setStatus(null); - var thirdCell = this.trElement.cells[2]; - if (thirdCell) { - if (thirdCell.originalHTML) { - thirdCell.innerHTML = thirdCell.originalHTML; - } else { - thirdCell.originalHTML = thirdCell.innerHTML; - } - } - }, - - onClick: function() { - if (this.trElement.isBreakpoint == undefined) { - this.trElement.isBreakpoint = true; - addClassName(this.trElement, "breakpoint"); - } else { - this.trElement.isBreakpoint = undefined; - removeClassName(this.trElement, "breakpoint"); - } - }, - - addBreakpointSupport: function() { - elementSetStyle(this.trElement, {"cursor" : "pointer"}); - this.trElement.onclick = fnBindAsEventListener(function() { - this.onClick(); - }, this); - }, - - isBreakpoint: function() { - if (this.trElement.isBreakpoint == undefined || this.trElement.isBreakpoint == null) { - return false - } - return this.trElement.isBreakpoint; - } -}); - -var HtmlTestSuiteRow = classCreate(); -objectExtend(HtmlTestSuiteRow.prototype, AbstractResultAwareRow.prototype); -objectExtend(HtmlTestSuiteRow.prototype, { - - initialize: function(trElement, testFrame, htmlTestSuite) { - this.trElement = trElement; - this.testFrame = testFrame; - this.htmlTestSuite = htmlTestSuite; - this.link = trElement.getElementsByTagName("a")[0]; - this.link.onclick = fnBindAsEventListener(this._onClick, this); - }, - - reset: function() { - this.setStatus(null); - }, - - _onClick: function() { - this.loadTestCase(null); - return false; - }, - - loadTestCase: function(onloadFunction) { - this.htmlTestSuite.unselectCurrentRow(); - this.select(); - this.htmlTestSuite.currentRowInSuite = this.trElement.rowIndex - 1; - // If the row has a stored results table, use that - var resultsFromPreviousRun = this.trElement.cells[1]; - if (resultsFromPreviousRun) { - // todo: delegate to TestFrame, e.g. - // this.testFrame.restoreTestCase(resultsFromPreviousRun.innerHTML); - var testBody = this.testFrame.getDocument().body; - testBody.innerHTML = resultsFromPreviousRun.innerHTML; - this.testFrame._onLoad(); - if (onloadFunction) { - onloadFunction(); - } - } else { - this.testFrame.load(this.link.href, onloadFunction); - } - }, - - saveTestResults: function() { - // todo: GLOBAL ACCESS! - var resultHTML = this.testFrame.getDocument().body.innerHTML; - if (!resultHTML) return; - - // todo: why create this div? - var divElement = this.trElement.ownerDocument.createElement("div"); - divElement.innerHTML = resultHTML; - - var hiddenCell = this.trElement.ownerDocument.createElement("td"); - hiddenCell.appendChild(divElement); - hiddenCell.style.display = "none"; - - this.trElement.appendChild(hiddenCell); - } - -}); - -var HtmlTestSuite = classCreate(); -objectExtend(HtmlTestSuite.prototype, { - - initialize: function(suiteDocument) { - this.suiteDocument = suiteDocument; - this.suiteRows = this._collectSuiteRows(); - var testTable = this.getTestTable(); - if (!testTable) return; - this.titleRow = new TitleRow(testTable.rows[0]); - this.reset(); - }, - - reset: function() { - this.failed = false; - this.currentRowInSuite = -1; - this.titleRow.setStatus(null); - for (var i = 0; i < this.suiteRows.length; i++) { - var row = this.suiteRows[i]; - row.reset(); - } - }, - - getSuiteRows: function() { - return this.suiteRows; - }, - - getTestTable: function() { - var tables = sel$A(this.suiteDocument.getElementsByTagName("table")); - return tables[0]; - }, - - isAvailable: function() { - return this.getTestTable() != null; - }, - - _collectSuiteRows: function () { - var result = []; - var tables = sel$A(this.suiteDocument.getElementsByTagName("table")); - var testTable = tables[0]; - if (!testTable) return; - for (rowNum = 1; rowNum < testTable.rows.length; rowNum++) { - var rowElement = testTable.rows[rowNum]; - result.push(new HtmlTestSuiteRow(rowElement, testFrame, this)); - } - - // process the unsuited rows as well - for (var tableNum = 1; tableNum < sel$A(this.suiteDocument.getElementsByTagName("table")).length; tableNum++) { - testTable = tables[tableNum]; - for (rowNum = 1; rowNum < testTable.rows.length; rowNum++) { - var rowElement = testTable.rows[rowNum]; - new HtmlTestSuiteRow(rowElement, testFrame, this); - } - } - return result; - }, - - getCurrentRow: function() { - if (this.currentRowInSuite == -1) { - return null; - } - return this.suiteRows[this.currentRowInSuite]; - }, - - unselectCurrentRow: function() { - var currentRow = this.getCurrentRow() - if (currentRow) { - currentRow.unselect(); - } - }, - - markFailed: function() { - this.failed = true; - this.titleRow.markFailed(); - }, - - markDone: function() { - if (!this.failed) { - this.titleRow.markPassed(); - } - }, - - _startCurrentTestCase: function() { - this.getCurrentRow().loadTestCase(fnBind(htmlTestRunner.startTest, htmlTestRunner)); - }, - - _onTestSuiteComplete: function() { - this.markDone(); - new SeleniumTestResult(this.failed, this.getTestTable()).post(); - }, - - updateSuiteWithResultOfPreviousTest: function() { - if (this.currentRowInSuite >= 0) { - this.getCurrentRow().saveTestResults(); - } - }, - - runNextTestInSuite: function() { - this.currentRowInSuite++; - - // If we are done with all of the tests, set the title bar as pass or fail - if (this.currentRowInSuite >= this.suiteRows.length) { - this._onTestSuiteComplete(); - } else { - this._startCurrentTestCase(); - } - } - - - -}); - -var SeleniumTestResult = classCreate(); -objectExtend(SeleniumTestResult.prototype, { - -// Post the results to a servlet, CGI-script, etc. The URL of the -// results-handler defaults to "/postResults", but an alternative location -// can be specified by providing a "resultsUrl" query parameter. -// -// Parameters passed to the results-handler are: -// result: passed/failed depending on whether the suite passed or failed -// totalTime: the total running time in seconds for the suite. -// -// numTestPasses: the total number of tests which passed. -// numTestFailures: the total number of tests which failed. -// -// numCommandPasses: the total number of commands which passed. -// numCommandFailures: the total number of commands which failed. -// numCommandErrors: the total number of commands which errored. -// -// suite: the suite table, including the hidden column of test results -// testTable.1 to testTable.N: the individual test tables -// - initialize: function (suiteFailed, suiteTable) { - this.controlPanel = htmlTestRunner.controlPanel; - this.metrics = htmlTestRunner.metrics; - this.suiteFailed = suiteFailed; - this.suiteTable = suiteTable; - }, - - post: function () { - if (!this.controlPanel.isAutomatedRun()) { - return; - } - var form = document.createElement("form"); - document.body.appendChild(form); - - form.id = "resultsForm"; - form.method = "post"; - form.target = "selenium_myiframe"; - - var resultsUrl = this.controlPanel.getResultsUrl(); - if (!resultsUrl) { - resultsUrl = "./postResults"; - } - - var actionAndParameters = resultsUrl.split('?', 2); - form.action = actionAndParameters[0]; - var resultsUrlQueryString = actionAndParameters[1]; - - form.createHiddenField = function(name, value) { - input = document.createElement("input"); - input.type = "hidden"; - input.name = name; - input.value = value; - this.appendChild(input); - }; - - if (resultsUrlQueryString) { - var clauses = resultsUrlQueryString.split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=', 2); - var key = unescape(keyValuePair[0]); - var value = unescape(keyValuePair[1]); - form.createHiddenField(key, value); - } - } - - form.createHiddenField("selenium.version", Selenium.version); - form.createHiddenField("selenium.revision", Selenium.revision); - - form.createHiddenField("result", this.suiteFailed ? "failed" : "passed"); - - form.createHiddenField("totalTime", Math.floor((this.metrics.currentTime - this.metrics.startTime) / 1000)); - form.createHiddenField("numTestPasses", this.metrics.numTestPasses); - form.createHiddenField("numTestFailures", this.metrics.numTestFailures); - form.createHiddenField("numCommandPasses", this.metrics.numCommandPasses); - form.createHiddenField("numCommandFailures", this.metrics.numCommandFailures); - form.createHiddenField("numCommandErrors", this.metrics.numCommandErrors); - - // Create an input for each test table. The inputs are named - // testTable.1, testTable.2, etc. - for (rowNum = 1; rowNum < this.suiteTable.rows.length; rowNum++) { - // If there is a second column, then add a new input - if (this.suiteTable.rows[rowNum].cells.length > 1) { - var resultCell = this.suiteTable.rows[rowNum].cells[1]; - form.createHiddenField("testTable." + rowNum, resultCell.innerHTML); - // remove the resultCell, so it's not included in the suite HTML - resultCell.parentNode.removeChild(resultCell); - } - } - - form.createHiddenField("numTestTotal", rowNum-1); - - // Add HTML for the suite itself - form.createHiddenField("suite", this.suiteTable.parentNode.innerHTML); - - var logMessages = []; - while (LOG.pendingMessages.length > 0) { - var msg = LOG.pendingMessages.shift(); - logMessages.push(msg.type); - logMessages.push(": "); - logMessages.push(msg.msg); - logMessages.push('\n'); - } - var logOutput = logMessages.join(""); - form.createHiddenField("log", logOutput); - - if (this.controlPanel.shouldSaveResultsToFile()) { - this._saveToFile(resultsUrl, form); - } else { - form.submit(); - } - document.body.removeChild(form); - if (this.controlPanel.closeAfterTests()) { - window.top.close(); - } - }, - - _saveToFile: function (fileName, form) { - // This only works when run as an IE HTA - var inputs = new Object(); - for (var i = 0; i < form.elements.length; i++) { - inputs[form.elements[i].name] = form.elements[i].value; - } - - var objFSO = new ActiveXObject("Scripting.FileSystemObject") - - // DGF get CSS - var styles = ""; - try { - var styleSheetPath = window.location.pathname.replace(/[^\/\\]+$/, "selenium-test.css"); - if (window.location.protocol == "file:") { - var stylesFile = objFSO.OpenTextFile(styleSheetPath, 1); - styles = stylesFile.ReadAll(); - } else { - var xhr = XmlHttp.create(); - xhr.open("GET", styleSheetPath, false); - xhr.send(""); - styles = xhr.responseText; - } - } catch (e) {} - - var scriptFile = objFSO.CreateTextFile(fileName); - - - scriptFile.WriteLine("Test suite results"); - scriptFile.WriteLine("\n

    Test suite results

    " + - "\n\n\n\n\n\n" + - "\n\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n\n" + - "\n\n\n
    result:" + inputs["result"] + "
    totalTime:" + inputs["totalTime"] + "
    numTestTotal:" + inputs["numTestTotal"] + "
    numTestPasses:" + inputs["numTestPasses"] + "
    numTestFailures:" + inputs["numTestFailures"] + "
    numCommandPasses:" + inputs["numCommandPasses"] + "
    numCommandFailures:" + inputs["numCommandFailures"] + "
    numCommandErrors:" + inputs["numCommandErrors"] + "
    " + inputs["suite"] + " 
    "); - var testNum = inputs["numTestTotal"]; - - for (var rowNum = 1; rowNum <= testNum; rowNum++) { - scriptFile.WriteLine("\n\n\n"); - } - scriptFile.WriteLine("
    " + inputs["testTable." + rowNum] + " 
    ");
    -        var log = inputs["log"];
    -        log=log.replace(/&/gm,"&").replace(//gm,">").replace(/"/gm,""").replace(/'/gm,"'");
    -        scriptFile.WriteLine(log);
    -        scriptFile.WriteLine("
    "); - scriptFile.Close(); - } -}); - -/** HtmlTestCase encapsulates an HTML test document */ -var HtmlTestCase = classCreate(); -objectExtend(HtmlTestCase.prototype, { - - initialize: function(testWindow, htmlTestSuiteRow) { - if (testWindow == null) { - throw "testWindow should not be null"; - } - if (htmlTestSuiteRow == null) { - throw "htmlTestSuiteRow should not be null"; - } - this.testWindow = testWindow; - this.testDocument = testWindow.document; - this.pathname = "'unknown'"; - try { - if (this.testWindow.location) { - this.pathname = this.testWindow.location.pathname; - } - } catch (e) {} - - this.htmlTestSuiteRow = htmlTestSuiteRow; - this.headerRow = new TitleRow(this.testDocument.getElementsByTagName("tr")[0]); - this.commandRows = this._collectCommandRows(); - this.nextCommandRowIndex = 0; - this._addBreakpointSupport(); - }, - - _collectCommandRows: function () { - var commandRows = []; - var tables = sel$A(this.testDocument.getElementsByTagName("table")); - var self = this; - for (var i = 0; i < tables.length; i++) { - var table = tables[i]; - var tableRows = sel$A(table.rows); - for (var j = 0; j < tableRows.length; j++) { - var candidateRow = tableRows[j]; - if (self.isCommandRow(candidateRow)) { - commandRows.push(new HtmlTestCaseRow(candidateRow)); - } - } - } - return commandRows; - }, - - isCommandRow: function (row) { - return row.cells.length >= 3; - }, - - reset: function() { - /** - * reset the test to runnable state - */ - this.nextCommandRowIndex = 0; - - this.setStatus(''); - for (var i = 0; i < this.commandRows.length; i++) { - var row = this.commandRows[i]; - row.reset(); - } - - // remove any additional fake "error" row added to the end of the document - var errorElement = this.testDocument.getElementById('error'); - if (errorElement) { - errorElement.parentNode.removeChild(errorElement); - } - }, - - getCommandRows: function () { - return this.commandRows; - }, - - setStatus: function(status) { - this.headerRow.setStatus(status); - }, - - markFailed: function() { - this.setStatus("failed"); - this.htmlTestSuiteRow.markFailed(); - }, - - markPassed: function() { - this.setStatus("passed"); - this.htmlTestSuiteRow.markPassed(); - }, - - addErrorMessage: function(errorMsg, currentRow) { - errorMsg = errorMsg.replace(/ /g, String.fromCharCode(160)).replace("\n", '\\n'); - if (currentRow) { - currentRow.markFailed(errorMsg); - } else { - var errorElement = this.testDocument.createElement("p"); - errorElement.id = "error"; - setText(errorElement, errorMsg); - this.testDocument.body.appendChild(errorElement); - errorElement.className = "status_failed"; - } - }, - - _addBreakpointSupport: function() { - for (var i = 0; i < this.commandRows.length; i++) { - var row = this.commandRows[i]; - row.addBreakpointSupport(); - } - }, - - hasMoreCommandRows: function() { - return this.nextCommandRowIndex < this.commandRows.length; - }, - - getNextCommandRow: function() { - if (this.hasMoreCommandRows()) { - return this.commandRows[this.nextCommandRowIndex++]; - } - return null; - } - -}); - - -// TODO: split out an JavascriptTestCase class to handle the "sejs" stuff - -var get_new_rows = function() { - var row_array = new Array(); - for (var i = 0; i < new_block.length; i++) { - - var new_source = (new_block[i][0].tokenizer.source.slice(new_block[i][0].start, - new_block[i][0].end)); - - var row = 'getEval' + - 'currentTest.doNextCommand()' + - '' + new_source + '' + - '' - - row_array.push(row); - } - return row_array; -}; - - -var Metrics = classCreate(); -objectExtend(Metrics.prototype, { - initialize: function() { - // The number of tests run - this.numTestPasses = 0; - // The number of tests that have failed - this.numTestFailures = 0; - // The number of commands which have passed - this.numCommandPasses = 0; - // The number of commands which have failed - this.numCommandFailures = 0; - // The number of commands which have caused errors (element not found) - this.numCommandErrors = 0; - // The time that the test was started. - this.startTime = null; - // The current time. - this.currentTime = null; - }, - - printMetrics: function() { - setText(sel$('commandPasses'), this.numCommandPasses); - setText(sel$('commandFailures'), this.numCommandFailures); - setText(sel$('commandErrors'), this.numCommandErrors); - setText(sel$('testRuns'), this.numTestPasses + this.numTestFailures); - setText(sel$('testFailures'), this.numTestFailures); - - this.currentTime = new Date().getTime(); - - var timeDiff = this.currentTime - this.startTime; - var totalSecs = Math.floor(timeDiff / 1000); - - var minutes = Math.floor(totalSecs / 60); - var seconds = totalSecs % 60; - - setText(sel$('elapsedTime'), this._pad(minutes) + ":" + this._pad(seconds)); - }, - -// Puts a leading 0 on num if it is less than 10 - _pad: function(num) { - return (num > 9) ? num : "0" + num; - }, - - resetMetrics: function() { - this.numTestPasses = 0; - this.numTestFailures = 0; - this.numCommandPasses = 0; - this.numCommandFailures = 0; - this.numCommandErrors = 0; - this.startTime = new Date().getTime(); - } - -}); - -var HtmlRunnerCommandFactory = classCreate(); -objectExtend(HtmlRunnerCommandFactory.prototype, { - - initialize: function(seleniumCommandFactory, testLoop) { - this.seleniumCommandFactory = seleniumCommandFactory; - this.testLoop = testLoop; - this.handlers = {}; - //todo: register commands - }, - - getCommandHandler: function(command) { - if (this.handlers[command]) { - return this.handlers[command]; - } - return this.seleniumCommandFactory.getCommandHandler(command); - } - -}); - -var HtmlRunnerTestLoop = classCreate(); -objectExtend(HtmlRunnerTestLoop.prototype, new TestLoop()); -objectExtend(HtmlRunnerTestLoop.prototype, { - initialize: function(htmlTestCase, metrics, seleniumCommandFactory) { - - this.commandFactory = new HtmlRunnerCommandFactory(seleniumCommandFactory, this); - this.metrics = metrics; - - this.htmlTestCase = htmlTestCase; - LOG.info("Starting test " + htmlTestCase.pathname); - - this.currentRow = null; - this.currentRowIndex = 0; - - // used for selenium tests in javascript - this.currentItem = null; - this.commandAgenda = new Array(); - this.expectedFailure = null; - this.expectedFailureType = null; - - this.htmlTestCase.reset(); - }, - - _advanceToNextRow: function() { - if (this.htmlTestCase.hasMoreCommandRows()) { - this.currentRow = this.htmlTestCase.getNextCommandRow(); - if (this.sejsElement) { - this.currentItem = agenda.pop(); - this.currentRowIndex++; - } - } else { - this.currentRow = null; - this.currentItem = null; - } - }, - - nextCommand : function() { - this._advanceToNextRow(); - if (this.currentRow == null) { - return null; - } - return this.currentRow.getCommand(); - }, - - commandStarted : function() { - sel$('pauseTest').disabled = false; - this.currentRow.select(); - this.metrics.printMetrics(); - }, - - commandComplete : function(result) { - this._checkExpectedFailure(result); - if (result.failed) { - this.metrics.numCommandFailures += 1; - this._recordFailure(result.failureMessage); - } else if (result.passed) { - this.metrics.numCommandPasses += 1; - this.currentRow.markPassed(); - } else { - this.currentRow.markDone(); - } - }, - - _checkExpectedFailure : function(result) { - if (this.expectedFailure != null) { - if (this.expectedFailureJustSet) { - this.expectedFailureJustSet = false; - return; - } - if (!result.failed) { - result.passed = false; - result.failed = true; - result.failureMessage = "Expected " + this.expectedFailureType + " did not occur."; - } else { - if (PatternMatcher.matches(this.expectedFailure, result.failureMessage)) { - var failureType = result.error ? "error" : "failure"; - if (failureType == this.expectedFailureType) { - result.failed = false; - result.passed = true; - } else { - result.failed = true; - result.failureMessage = "Expected "+this.expectedFailureType+", but "+failureType+" occurred instead"; - } - } else { - result.failed = true; - result.failureMessage = "Expected " + this.expectedFailureType + " message '" + this.expectedFailure - + "' but was '" + result.failureMessage + "'"; - } - } - this.expectedFailure = null; - this.expectedFailureType = null; - } - }, - - commandError : function(errorMessage) { - var tempResult = {}; - tempResult.passed = false; - tempResult.failed = true; - tempResult.error = true; - tempResult.failureMessage = errorMessage; - this._checkExpectedFailure(tempResult); - if (tempResult.passed) { - this.currentRow.markDone(); - return true; - } - errorMessage = tempResult.failureMessage; - this.metrics.numCommandErrors += 1; - this._recordFailure(errorMessage); - }, - - _recordFailure : function(errorMsg) { - LOG.warn("currentTest.recordFailure: " + errorMsg); - htmlTestRunner.markFailed(); - this.htmlTestCase.addErrorMessage(errorMsg, this.currentRow); - }, - - testComplete : function() { - sel$('pauseTest').disabled = true; - sel$('stepTest').disabled = true; - if (htmlTestRunner.testFailed) { - this.htmlTestCase.markFailed(); - this.metrics.numTestFailures += 1; - } else { - this.htmlTestCase.markPassed(); - this.metrics.numTestPasses += 1; - } - - this.metrics.printMetrics(); - - window.setTimeout(function() { - htmlTestRunner.runNextTest(); - }, 1); - }, - - getCommandInterval : function() { - return htmlTestRunner.controlPanel.runInterval; - }, - - pause : function() { - htmlTestRunner.controlPanel.pauseCurrentTest(); - }, - - doNextCommand: function() { - var _n = this.currentItem[0]; - var _x = this.currentItem[1]; - - new_block = new Array() - execute(_n, _x); - if (new_block.length > 0) { - var the_table = this.htmlTestCase.testDocument.getElementById("se-js-table") - var loc = this.currentRowIndex - var new_rows = get_new_rows() - - // make the new statements visible on screen... - for (var i = 0; i < new_rows.length; i++) { - the_table.insertRow(loc + 1); - the_table.rows[loc + 1].innerHTML = new_rows[i]; - this.commandRows.unshift(the_table.rows[loc + 1]) - } - - } - } - -}); - -Selenium.prototype.doPause = function(waitTime) { - /** Wait for the specified amount of time (in milliseconds) - * @param waitTime the amount of time to sleep (in milliseconds) - */ - // todo: should not refer to currentTest directly - currentTest.pauseInterval = waitTime; -}; - -Selenium.prototype.doBreak = function() { - /** Halt the currently running test, and wait for the user to press the Continue button. - * This command is useful for debugging, but be careful when using it, because it will - * force automated tests to hang until a user intervenes manually. - */ - // todo: should not refer to controlPanel directly - htmlTestRunner.controlPanel.setToPauseAtNextCommand(); -}; - -Selenium.prototype.doStore = function(expression, variableName) { - /** This command is a synonym for storeExpression. - * @param expression the value to store - * @param variableName the name of a variable in which the result is to be stored. - */ - storedVars[variableName] = expression; -} - -/* - * Click on the located element, and attach a callback to notify - * when the page is reloaded. - */ -// DGF TODO this code has been broken for some time... what is it trying to accomplish? -Selenium.prototype.XXXdoModalDialogTest = function(returnValue) { - this.browserbot.doModalDialogTest(returnValue); -}; - -Selenium.prototype.doEcho = function(message) { - /** Prints the specified message into the third table cell in your Selenese tables. - * Useful for debugging. - * @param message the message to print - */ - currentTest.currentRow.setMessage(message); -} - -/* - * doSetSpeed and getSpeed are already defined in selenium-api.js, - * so we're defining these functions in a tricky way so that doc.js doesn't - * try to read API doc from the function definitions here. - */ -Selenium.prototype._doSetSpeed = function(value) { - var milliseconds = parseInt(value); - if (milliseconds < 0) milliseconds = 0; - htmlTestRunner.controlPanel.speedController.setValue(milliseconds); - htmlTestRunner.controlPanel.setRunInterval(milliseconds); -} -Selenium.prototype.doSetSpeed = Selenium.prototype._doSetSpeed; - -Selenium.prototype._getSpeed = function() { - return htmlTestRunner.controlPanel.runInterval; -} -Selenium.prototype.getSpeed = Selenium.prototype._getSpeed; - -Selenium.prototype.assertSelected = function(selectLocator, optionLocator) { - /** - * Verifies that the selected option of a drop-down satisfies the optionSpecifier. Note that this command is deprecated; you should use assertSelectedLabel, assertSelectedValue, assertSelectedIndex, or assertSelectedId instead. - * - *

    See the select command for more information about option locators.

    - * - * @param selectLocator an element locator identifying a drop-down menu - * @param optionLocator an option locator, typically just an option label (e.g. "John Smith") - */ - var element = this.page().findElement(selectLocator); - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - if (element.selectedIndex == -1) - { - Assert.fail("No option selected"); - } - locator.assertSelected(element); -}; - -Selenium.prototype.assertFailureOnNext = function(message) { - /** - * Tell Selenium to expect a failure on the next command execution. - * @param message The failure message we should expect. This command will fail if the wrong failure message appears. - */ - if (!message) { - throw new SeleniumError("Message must be provided"); - } - - currentTest.expectedFailure = message; - currentTest.expectedFailureType = "failure"; - currentTest.expectedFailureJustSet = true; -}; - -Selenium.prototype.assertErrorOnNext = function(message) { - /** - * Tell Selenium to expect an error on the next command execution. - * @param message The error message we should expect. This command will fail if the wrong error message appears. - */ - // This command temporarily installs a CommandFactory that generates - // CommandHandlers that expect an error. - if (!message) { - throw new SeleniumError("Message must be provided"); - } - - currentTest.expectedFailure = message; - currentTest.expectedFailureType = "error"; - currentTest.expectedFailureJustSet = true; -}; - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-version.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-version.js deleted file mode 100644 index 5334c07b..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-version.js +++ /dev/null @@ -1,5 +0,0 @@ -Selenium.version = "1.0-beta-2"; -Selenium.revision = "2330"; - -window.top.document.title += " v" + Selenium.version + " [" + Selenium.revision + "]"; - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-doc.html b/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-doc.html deleted file mode 100644 index fe7d20d4..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-doc.html +++ /dev/null @@ -1,803 +0,0 @@ - - -Selenium UI-Element Reference - - - - - -

    Selenium UI-Element Reference

    - -

    Introduction

    - -

    UI-Element is a Selenium feature that makes it possible to define a mapping between semantically meaningful names of elements on webpages, and the elements themselves. The mapping is defined using JavaScript Object Notation, and may be shared both by the IDE and tests run via Selenium RC. It also offers a single point of update should the user interface of the application under test change.

    - -

    Terminology

    - -
    -
    Page
    -
    A unique URL, and the contents available by accessing that URL. A page typically consists of several interactive page elements. A page may also be considered a DOM document object, complete with URL information.
    -
    Page element
    -
    An element on the actual webpage. Generally speaking, an element is anything the user might interact with, or anything that contains meaningful content. More specifically, an element is realized as a Document Object Model (DOM) node and its contents. So when we refer to a page element, we mean both of the following, at the same time: -
      -
    • something on the page
    • -
    • its DOM representation, including its relationship with other page elements
    • -
    -
    -
    Pageset
    -
    A set of pages that share some set of common page elements. For example, I might be able to log into my application from several different pages. If certain page elements on each of those pages appear similarly (i.e. their DOM representations are identical), those pages can be grouped into a pageset with respect to these page elements. There is no restriction on how many pagesets a given page can be a member of. Similarly, a UI element belong to multiple pagesets. A pageset is commonly represented by a regular expression which matches the URL's that uniquely identify pages; however, there are cases when the page content must be considered to determine pageset membership. A pageset also has a name.
    -
    UI element
    -
    A mapping between a meaningful name for a page element, and the means to locate that page element's DOM node. The page element is located via a locator. UI elements belong to pagesets.
    -
    UI argument
    -
    An optional piece of logic that determines how the locator is generated by a UI element. Typically used when similar page elements appear multiple times on the same page, and you want to address them all with a single UI element. For example, if a page presents 20 clickable search results, the index of the search result might be a UI argument.
    -
    UI map
    -
    A collection of pagesets, which in turn contain UI elements. The UI map is the medium for translating between UI specifier strings, page elements, and UI elements.
    -
    UI specifier string
    -
    A bit of text containing a pageset name, a UI element name, and optionally arguments that modify the way a locator is constructed by the UI element. UI specifier strings are intended to be the human-readable identifier for page elements.
    -
    Rollup rule
    -
    Logic that describes how one or more Selenium commands can be grouped into a single command, and how that single command may be expanded into its component Selenium commands. The single command is referred to simply as a "rollup".
    -
    Command matcher
    -
    Typically folded into a rollup rule, it matches one or more Selenium commands and optionally sets values for rollup arguments based on the matched commands. A rollup rule usually has one or more command matchers.
    -
    Rollup argument
    -
    An optional piece of logic that modifies the command expansion of a rollup.
    -
    - -

    The Basics

    - -

    Getting Motivated

    - -

    Question: Why use UI-Element? Answer: So your testcases can look like this (boilerplate code omitted):

    - -
    -<tr>
    -    <td>open</td>
    -    <td>/</td>
    -    <td></td>
    -</tr>
    -<tr>
    -    <td>clickAndWait</td>
    -    <td>ui=allPages::section(section=topics)</td>
    -    <td></td>
    -</tr>
    -<tr>
    -    <td>clickAndWait</td>
    -    <td>ui=topicListingPages::topic(topic=Process)</td>
    -    <td></td>
    -</tr>
    -<tr>
    -    <td>clickAndWait</td>
    -    <td>ui=subtopicListingPages::subtopic(subtopic=Creativity)</td>
    -    <td></td>
    -</tr>
    -<tr>
    -    <td>click</td>
    -    <td>ui=subtopicArticleListingPages::article(index=2)</td>
    -    <td></td>
    -</tr>
    -
    - -

    Including the Right Files

    - -

    UI-Element is now fully integrated with Selenium. The only additional file that needs to be specified is your map definitions file. In the IDE, add it to the comma-delimited Selenium Core extensions field of the IDE options. A sample definition file created for the website alistapart.com is included in the distribution and is available here:

    - -
    chrome://selenium-ide/content/selenium/scripts/ui-map-sample.js
    - -

    You might want to experiment with the sample map to get a feel for UI-Element. For the Selenium RC, you have two options. The map file may be included in the user-extensions.js file specified at startup with the -userExtensions switch. Or, you may load it dynamically with the variant of the setUserExtensionJs command in your driver language, before the browser is started.

    - -

    Map Definitions File Syntax

    - -

    This is the general format of a map file:

    - -
    -var map = new UIMap();
    -
    -map.addPageset({
    -    name: 'aPageset'
    -    , ... 
    -});
    -map.addElement('aPageset', { ... });
    -map.addElement('aPageset', { ... });
    -...
    -
    -map.addPageset({
    -    name: 'anotherPageset'
    -    , ... 
    -});
    -...
    -
    - -

    The map object is initialized by creating a new UIMap object. Next, a pageset is defined. Then one or more UI elements are defined for that pageset. More pagesets are defined, each with corresponding UI elements. That's it!

    - -

    Pageset Shorthand

    - -

    The method signature of addPageset() is (pagesetShorthand). pagesetShorthand is a JSON description of the pageset. Here's a minimal example:

    - -
    -map.addPageset({
    -    name: 'allPages'
    -    , description: 'contains elements common to all pages'
    -    , pathRegexp: '.*'
    -});
    -
    - -

    Here's a table containing information about the attributes of the Pageset object. The conditionally required or unrequired items are for IDE recording support only.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRequired?DescriptionExample
    nameYes(String) the name of the pageset. This should be unique within the map.
    name: 'shopPages'
    descriptionYes(String) a description of the pageset. Ideally, this will give the reader an idea of what types of UI elements the pageset will have.
    description: 'all pages displaying product'
    pathPrefixNo(String) the path of the URL of all included pages in this pageset will contain this prefix. For example, if all pages are of the form http://www.example.com/gallery/light-show/, the page prefix might be gallery/ .
    pathPrefix: 'gallery/'
    paths
    pathRegexp
    Conditional(Array | String) either a list of path strings, or a string that represents a regular expression. One or the other should be defined, but not both. If an array, it enumerates pages that are included in the pageset. If a regular expression, any pages whose URL paths match the expression are considered part of the pageset. In either case, the part of the URL being matched (called the path) is the part following the domain, less any training slash, and not including the CGI parameters. For example: -
      -
    • http://www.example.com/articles/index.php
    • -
    • http://www.example.com/articles/2579?lang=en_US
    • -
    • http://www.example.com/articles/selenium/
    • -
    - The entire path must match (however, pathPrefix is taken into account if specified). If specified as a regular expression, the two regular expression characters ^ and $ marking the start and end of the matched string are included implicitly, and should not be specified in this string. Please notice too that backslashes must be backslash-escaped in javascript strings.
    paths: [
    -    'gotoHome.do'
    -    , 'gotoAbout.do'
    -    , 'gotoFaq.do'
    -]
    -
    pathRegexp: 'goto(Home|About|Faq)\\.do'
    -
    paramRegexpsNo(Object) a mapping from URL parameter names to regular expression strings which must match their values. If specified, the set of pages potentially included in this pageset will be further filtered by URL parameter values. There is no filtering by parameter value by default.
    paramRegexps: {
    -    dept: '^[abcd]$'
    -    , team: 'marketing'
    -}
    pageContentConditional

    (Function) a function that tests whether a page, represented by its document object, is contained in the pageset, and returns true if and only if this is the case. If specified, the set of pages potentially included in this pageset will be further filtered by content, after URL and URL parameter filtering.

    -

    Since the URL is available from the document object (document.location.href), you may encode the logic used for the paths and pathRegexp attributes all into the definition of pageContent. Thus, you may choose to omit the former if and only if using pageContent. Of course, you may continue to use them for clarity.

    pageContent: function(doc) {
    -    var id = 'address-tab';
    -    return doc.getElementById(id) != null;
    -}
    - -

    UI-Element Shorthand

    - -

    The method signature of addElement() is (pagesetName, uiElementShorthand). pagesetName is the name of the pageset the UI element is being added to. uiElementShorthand is a complete JSON description of the UI element object in shorthand notation.

    - -

    In its simplest form, a UI element object looks like this:

    - -
    -map.addElement('allPages', {
    -    name: 'about_link'
    -    , description: 'link to the about page'
    -    , locator: "//a[contains(@href, 'about.php')]"
    -});
    -
    - -

    Here's a table containing information about the attributes of the UI element object. The asterisk (*) means any string:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRequired?DescriptionExample
    nameYes(String) the name of the UI element
    name: 'article'
    descriptionYes(String) a description of the UI element. This is the main documentation for this UI element, so the more detailed, the better.
    description: 'front or issue page link to article'
    argsNo(Array) a list of arguments that modify the getLocator() method. If unspecified, it will be treated as an empty list.
    [
    -    { name: 'index'
    -    , description: 'the index of the author, by article'
    -    , defaultValues: range(1, 5) }
    -]
    See section below elaborating on attributes of argument objects.
    locator
    getLocator()
    xpathgetXPath()
    Yes

    (String | Function) either a fixed locator string, or a function that returns a locator string given a set of arguments. One or the other should be defined, but not both. Under the sheets, the locator attribute eventually gets transcripted as a getLocator() function.

    As of ui0.7, xpath and getXPath() have been deprecated. They are still supported for backward compatibility.

    locator: 'submit'
    -
    getLocator: function(args) {
    -    return 'css=div.item:nth-child(' + args.index + ')'
    -        + ' > h5 > a';
    -}
    -
    getLocator: function(args) {
    -    var label = args.label;
    -    var id = this._idMap[label];
    -    return '//input[@id=' + id.quoteForXPath() + ']';
    -}
    genericLocator
    getGenericLocator
    No

    (String | Function) either a fixed locator string, or a function that returns a locator string. If a function, it should take no arguments.

    You may experience some slowdown when recording on pages where individual UI elements have many default locators (due to many permutations of default values over multiple arguments). This is because each default locator is potentially evaluated and matched against the interacted page element. This becomes especially problematic if several UI elements have this characteristic.

    By specifying a generic locator, you give the matching engine a chance to skip over UI elements that definitely don't match. The default locators for skipped elements will not be evaluated unless the generic locator matches the interacted page element..

    genericLocator: "//table[@class='ctrl']"
    -    + "/descendant::input"
    -
    getGenericLocator: function() {
    -    return this._xpathPrefix + '/descendant::a';
    -}
    -
    getOffsetLocatorNo

    (Function) a function that returns an offset locator. The locator is offset from the element identified by a UI specifier string. The function should take this element, and the interacted page element, as arguments, and have the method signature getOffsetLocator(locatedElement, pageElement). If an offset locator can't be found, a value that evaluates to false must be returned.

    A convenient default function UIElement.defaultOffsetLocatorStrategy is provided so you don't have to define your own. It uses several typical strategies also employed by the IDE recording when recording normally. See the Advanced Topics section below for more information on offset locators.

    getOffsetLocator: UIElement.defaultOffsetLocatorStrategy
    -
    getOffsetLocator:
    -    function(locatedElement, pageElement) {
    -    if (pageElement.parentNode == locatedElement) {
    -        return '/child::' + pageElement.nodeName;
    -    }
    -    return null;
    -}
    testcase*No(Object) a testcase for testing the implementation of the getLocator() method. As many testcases as desired may be defined for each UI element. They must all start with the string "testcase".
    testcase1: {
    -    xhtml: '<div class="item"><h5>'
    -        + '<a expected-result="1" /></h5></div>'
    -}
    See section below elaborating on testcases.
    _*No(Any data type) a "local variable" declared for the UI element. This variable will be available both within the getLocator() method of the UI element, and any getDefaultValues() methods of the arguments via the this keyword. They must all start with an underscore "_".
    _labelMap: {
    -    'Name': 'user'
    -    , 'Email': 'em'
    -    , 'Phone': 'tel'
    -}
    - -

    UI-Argument Shorthand

    - -

    UI arguments are defined as part of UI elements, and help determine how an XPath is generated. A list of arguments may be defined within the UI element JSON shorthand. Here's an example of how that might look:

    - -
    -map.addElement('searchPages', {
    -    name: 'result'
    -    , description: 'link to a result page'
    -    , args: [
    -        {
    -            name: 'index'
    -            , description: 'the index of the search result'
    -            , defaultValues: range(1, 21)
    -        }
    -        , {
    -            name: 'type'
    -            , description: 'the type of result page'
    -            , defaultValues: [ 'summary', 'detail' ]
    -        }
    -    ]
    -    , getLocator: function(args) {
    -        var index = args['index'];
    -        var type = args['type'];
    -        return "//div[@class='result'][" + index + "]"
    -            + "/descendant::a[@class='" + type + "']";
    -    }
    -});
    -
    - -

    In the above example, two arguments are defined, index and type. Metadata is provided to describe them, and default values are also specified. FInally, the getLocator() method is defined. The behavior of the method depends on the values of the arguments that are passed in.

    - -

    Default values come into play when recording tests using the Selenium IDE. When you interact with a page element in recording mode, the IDE uses all the locator strategies at its disposal to deduce an appropriate locator string for that element. UI-Element introduces a new ui locator strategy. When applying this strategy using a particular UI element, Selenium generates a list of XPaths to try by permuting the arguments of that UI element over all default values. Here, the default values { 1, 2, 3, 4 .. 20 } are given for the index argument using the special range() function, and the values { summary, detail } are given for the type argument in standard javascript array notation. If you don't intend to use the IDE, go ahead and set the default values to the empty array [].

    - -

    Here's a table containing information about the attributes of the UI argument object.

    - - - - - - - - - - - - - - - - - - - - - - -
    NameRequired?DescriptionExample
    nameYes(String) the name of the argument. This will be the name of the property of the object passed into the parent UI element's getLocator() method containing the argument value.
    name: 'index'
    descriptionYes(String) a description for the argument.
    description: 'the index of the article'
    defaultValues
    getDefaultValues()
    Yes

    (Array | Function) either an array of string or numerical values, or a function that returns an array of string or numerical values. One or the other should be defined, but not both. Under the sheets, the defaultValues attribute eventually gets transcripted as a getDefaultValues() function.

    The method signature of the function is getDefaultValues(inDocument). inDocument is the current document object of the page at time of recording. In cases where the default values are known a priori, inDocument need not be used. If the default values of all arguments of a UI element are known a priori, the list of default locators for the element may be precalculated, resulting in better performance. If inDocument is used, in cases where the current document is inspected for valid values, the element's default locators are calculated once for every recordable event.

    defaultValues: [ 'alpha', 'beta', 'unlimited' ]
    -
    getDefaultValues: function() {
    -    return keys(this._idMap);
    -}
    -
    getDefaultValues: function(inDocument) {
    -    var defaultValues = [];
    -    var links = inDocument
    -        .getElementsByTagName('a');
    -    for (var i = 0; i < links.length; ++i) {
    -        var link = links[i];
    -        if (link.className == 'category') {
    -            defaultValues.push(link.innerHTML);
    -        }
    -    }
    -    return defaultValues;
    -}
    - -

    About this

    - -

    You may have noticed usage of the this keyword in the examples above, specifically in the getLocator() and getDefaultValues() methods. Well, what exactly is this?

    - -

    The answer is: it depends. The object referred to by this changes depending on the context in which it is being evaluated. At the time of object creation using addPageset() or addElement(), it refers to the window object of the Selenium IDE, which isn't useful at all. However, subsequently any time getLocator() is called, its this references the UI element object it's attached too. Thus, using this, any "local variables" defined for the UI element may be accessed. Similarly, when getDefaultValues() is called, its this references the UI argument object it's attached too. But ... what "local variables" are accessible by the from getDefaultValues()?

    - -

    There's a little magic here. If you defined your local variables as prescribed in the above UI-Element Shorthand section, starting with an underscore, those variable are automatically made available to the UI argument via its this keyword. Note that this isn't standard javascript behavior. It's implemented this way to clear out clutter in the method definitions and to avoid the use of global variables for lists and maps used within the methods. It is sometimes useful, for example, to define an object that maps human-friendly argument values to DOM element id's. In such a case, getDefaultValues() can be made to simply return the keys() (or property names) of the map, while the getLocator() method uses the map to retrieve the associated id to involve in the locator.

    - -

    Also note that this only behaves this way in the two mentioned methods, getLocator() and getDefaultValues(); in other words you can't reference the UI element's local variables using this outside of methods.

    - -

    If you're interested, here's some additional reading on javascript scope.

    - -

    Advanced Topics

    - -

    Testcases

    - -

    You can write testcases for your UI element implementations that are run every time the Selenium IDE is started. Any testcases that fail are reported on. The dual purpose of writing testcases is to both validate the getLocator() method against a representation of the real page under test, and to give a visual example of what the DOM context of a page element is expected to be.

    - -

    A testcase is an object with a required xhtml property (String), and a required args property (Object). An example is due:

    - -
    -testcase1: {
    -    args: { line: 2, column: 3 }
    -    , xhtml: '<table id="scorecard">'
    -        + '<tr class="line" />'
    -        + '<tr class="line"><td /><td /><td expected-result="1" /></tr>'
    -        + '</table>'
    -}
    -
    - -

    The args property specifies the object to be passed into the UI element's getLocator() method to generate the test locator, which is then applied to the xhtml. If evaluating the locator on the XHTML document returns a DOM node with the expected-result attribute, the testcase is considered to have passed.

    - -

    The xhtml property must represent a complete XML document, sans <html> tags, which are automatically added. The reason this is necessary is that the text is being converted into an XPath evaluable DOM tree via Mozilla's native XML parser. Unfortunately, there is no way to generate a simple HTML document, only XML documents. This means that the content of the xhtml must be well-formed. Tags should also be specified in lowercase.

    - -

    Fuzzy Matching

    - -

    Here's a real-world example of where fuzzy matching is important:

    - -
    -<table>
    -<tr onclick="showDetails(0)">
    -    <td>Brahms</td>
    -    <td>Viola Quintet</td>
    -</tr>
    -<tr onclick="showDetails(1)">
    -    <td>Saegusa</td>
    -    <td>Cello 88</td>
    -</tr>
    -</table>
    -
    - -

    Imagine I'm recording in the IDE. Let's say I click on "Cello 88". The IDE would create locator for this action like //table/tr[2]/td[2]. Does that mean that my getLocator() method should return the same XPath?

    - -

    Clearly not. Clicking on either of the table cells for the second row has the same result. I would like my UI element generated XPath to be //table/tr[2] . However, when recording, the page element that was identified as being acted upon was the table cell, which doesn't match my UI element XPath, so the ui locator strategy will fail to auto-populate. What to do?

    - -

    Fuzzy matching to the rescue! Fuzzy matching is realized as a fuzzy matcher function that returns true if a target DOM element is considered to be equivalent to a reference DOM element. The reference DOM element would be the element specified by the UI element's generated XPath. Currently, the fuzzy matcher considers it a match if: - -

      -
    • the elements are the same element,
    • -
    • the reference element is an anchor (<a>) element, and the target element is a descendant of it; or
    • -
    • the reference element has an onclick attribute, and the target element is a descendant of it.
    • -
    - -

    This logic may or may not be sufficient for you. The good news is, it's very easy to modify. Look for the definition of BrowserBot.prototype.locateElementByUIElement.is_fuzzy_match in ui-element.js .

    - -

    Offset Locators

    - -

    Offset locators are locators that are appended to UI specifier strings to form composite locators. They can be automatically deduced by the IDE recorder for UI elements that have specified a getOffsetLocator function. This feature may be useful if your pages contain too many elements to write UI elements for. In this case, offset locators allow you to define UI elements that "anchor" other elements. Given the following markup:

    - -
    <form name="contact_info">
    -    <input type="text" name="foo" />
    -    <textarea name="bar"></textarea>
    -    <input type="submit" value="baz" />
    -</form>
    - -

    Assume that a UI element has been defined for the form element. Then the following locators containing offset locators and "anchored" off this element would be recorded using the default offset locator function (UIElement.defaultOffsetLocatorStrategy):

    - -
    ui=contactPages::contact_form()->//input[@name='foo']
    -ui=contactPages::contact_form()->//textarea[@name='bar']
    -ui=contactPages::contact_form()->//input[@value='baz']
    - -

    The character sequence -> serves to delimit the offset locator from the main locator. For this reason, the sequence should not appear in the main locator, or else ambiguity will result.

    - -

    When recording with the IDE, no preference is given to matching plain vanilla UI specifier strings over ones that have offset locators. In other words, if a page element could be specified both by a UI specifier string for one UI element, and by one augmented by an offset locator for a different UI element, there is no guarantee that one or the other locator will be recorded.

    - -

    Currently, only XPath is supported as an offset locator type, as it is the only locator for which a context node can be specified at evaluation time. Other locator strategies may be supported in the future.

    - -

    Rollup Rules

    - -

    Question: Why use rollup rules? Answer: Remember the testcase from the "Getting Motivated" section above? With rollups, that testcase can be condensed into this:

    - -
    -<tr>
    -    <td>open</td>
    -    <td>/</td>
    -    <td></td>
    -</tr>
    -<tr>
    -    <td>rollup</td>
    -    <td>navigate_to_subtopic_article</td>
    -    <td>index=2, subtopic=Creativity</td>
    -</tr>
    -
    - -

    It's inevitable that certain sequences of Selenium commands will appear in testcases over and over again. When this happens, you might wish to group several fine-grained commands into a single coarser, more semantically meaningful action. In doing so, you would abstract out the execution details for the action, such that if they were to change at some point, you would have a single point of update. In UI-Element, such actions are given their own command, called rollup. In a sense, rollups are a natural extension of the ui locator.

    - -

    UI-Element is designed with the belief that the IDE can be a useful tool for writing testcases, and need not be shunned for lack of functionality. A corollary belief is that you should be able to drive your RC test in the language of your choice. The execution of the rollup command by the Selenium testrunner produces the component commands, which are executed in a new context, like a function call. The logic of the rollup "expansion" is written in javascript. Corresponding logic for inferring a rollup from a list of commands is also written in javascript. Thus, the logic can be incorporated into any of the family of Selenium products as a user extension. Most notably, the IDE is made viable as a testcase creation tool that understands both how rollups expand to commands, and also how rollup rules can be "applied" to commands to reduce them to rollups.

    - -

    Rollup rule definitions appear in this general format:

    - -
    -var manager = new RollupManager();
    -
    -manager.addRollupRule({ ... });
    -manager.addRollupRule({ ... });
    -...
    -
    - -

    In a relatively simple form, a rollup rule looks like this:

    - -
    -manager.addRollupRule({
    -    name: 'do_search'
    -    , description: 'performs a search'
    -    , args: [
    -        name: 'term'
    -        , description: 'the search term'
    -    ]
    -    , commandMatchers: [
    -        {
    -            command: 'type'
    -            , target: 'ui=searchPages::search_box\\(.+'
    -            , updateArgs: function(command, args) {
    -                var uiSpecifier = new UISpecifier(command.target);
    -                args.term = uiSpecifier.args.term;
    -                return args;
    -            }
    -        }
    -        , {
    -            command: 'click.+'
    -            , target: 'ui=searchPages::search_go\\(.+'
    -        }
    -    ]
    -    , getExpandedCommands: function(args) {
    -        var commands = [];
    -        var uiSpecifier = new UISpecifier(
    -            'searchPages'
    -            , 'search_box'
    -            , { term: args.term });
    -        commands.push({
    -            command: 'type'
    -            , target: 'ui=' + uiSpecifier.toString()
    -        });
    -        commands.push({
    -            command: 'clickAndWait'
    -            , target: 'ui=searchPages::search_go()'
    -        });
    -        return commands;
    -    }
    -});
    -
    - -

    In the above example, a rollup rule is defined for performing a search. The rule can be "applied" to two consecutive commands that match the commandMatchers. The rollup takes one argument, term, and expands back to the original two commands. One thing to note is that the second command matcher will match all commands starting with click. The rollup will expand that command to a clickAndWait.

    - -

    Here's a table containing information about the attributes of the rollup rule object.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRequired?DescriptionExample
    nameYes(String) the name of the rollup rule. This will be the target of the resulting rollup command.
    name: 'do_login'
    descriptionYes(String) a description for the rollup rule.
    description: 'logs into the application'
    alternateCommandNo(String) specifies an alternate usage of rollup rules to replace commands. This string is used to replace the command name of the first matched command.
    alternateCommand: 'clickAndWait'
    preNo(String) a detailed summary of the preconditions that must be satisfied for the rollup to execute successfully. This metadata is easily viewable in the IDE when the rollup command is selected.
    pre: 'the page contains login widgets'
    postNo(String) a detailed summary of the postconditions that will exist after the rollup has been executed.
    post: 'the user is logged in, or is \
    -directed to a login error page'
    argsConditional

    (Array) a list of arguments that are used to modify the rollup expansion. These are similar to UI arguments, with the exception that exampleValues are provided, instead of defaultValues. Here, example values are used for reference purposes only; they are displayed in the rollup pane in the IDE.

    This attribute may be omitted if no updateArgs() functions are defined for any command matchers.

    args: {
    -    name: 'user'
    -    , description: 'the username to login as'
    -    , exampleValues: [
    -        'John Doe'
    -        , 'Jane Doe'
    -    ]
    -}
    commandMatchers
    getRollup()
    Yes

    (Array | Function) a list of command matcher definitions, or a function that, given a list of commands, returns either 1) a rollup command if the rule is considered to match the commands (starting at the first command); or 2) false. If a function, it should have the method signature getRollup(commands), and the returned rollup command (if any) must have the replacementIndexes attribute, which is a list of array indexes indicating which commands in the commands parameter are to be replaced.

    -

    If you don't intend on using the IDE with your rollups, go ahead and set this to the empty array [].

    commandMatchers: [
    -    {
    -        command: 'type'
    -        , target: 'ui=loginPages::user\\(.+'
    -        , value: '.+'
    -        , minMatches: 1
    -        , maxMatches: 1
    -        , updateArgs:
    -            function(command, args) {
    -            args.user = command.value;
    -            return args;
    -        }
    -    }
    -]
    -
    // this is a simplistic example, roughy
    -// equivalent to the commandMatchers
    -// example above. The to_kwargs() function
    -// is used to turn an arguments object into
    -// a keyword-arguments string.
    -getRollup: function(commands) {
    -    var command = commands[0];
    -    var re = /^ui=loginPages::user\(.+/;
    -    if (command.command == 'type' &&
    -        re.test(command.target) &&
    -        command.value) {
    -        var args = { user: command.value };
    -        return {
    -            command: 'rollup'
    -            , target: this.name
    -            , value: to_kwargs(args)
    -            , replacementIndexes: [ 0 ]
    -        };
    -    }
    -    return false;
    -}
    See section below elaborating on command matcher objects.
    expandedCommands
    getExpandedCommands()
    Yes

    (Array | Function) a list of commands the rollup command expands into, or a function that, given an argument object mapping argument names to values, returns a list of expanded commands. If a function, it should have the method signature getExpandedCommands(args).

    Each command in the list of expanded commands should contain a command attribute, which is the name of the command, and optionally target and value attributes, depending on the type of command.

    It is expected that providing a fixed list of expanded commands will be of limited use, as rollups will typically contain commands that have arguments, requiring more sophisticated logic to expand.

    expandedCommands: [
    -    {
    -        command: 'check'
    -        , target: 'ui=termsPages::agree\\(.+'
    -    }
    -    , {
    -        command: 'clickAndWait'
    -        , target: 'ui=termsPages::submit\\(.+'
    -    }
    -]
    -
    getExpandedCommands: function(args) {
    -    var commands = [];
    -    commands.push({
    -        command: 'type'
    -        , target: 'ui=loginPages::user()'
    -        , value: args.user
    -    });
    -    commands.push({
    -        command: 'type'
    -        , target: 'ui=loginPages::pass()'
    -        , value: args.pass
    -    });
    -    commands.push({
    -        command: 'clickAndWait'
    -        , target: 'ui=loginPages::submit()'
    -    });
    -    commands.push({
    -        command: 'verifyLocation'
    -        , target: 'regexp:.+/home'
    -    });
    -    return commands;
    -}
    -
    // if using alternateCommand
    -expandedCommands: []
    -
    - -

    The user should be able to freely record commands in the IDE, which can be collapsed into rollups at any point by applying the defined rollup rules. Healthy usage of the ui locator makes commands easy to match using command matcher definitions. Command matchers simplify the specification of a command match. In basic usage, for a rollup rule, you might specify 3 command matchers: M1, M2, and M3, that you intend to match 3 corresponding commands, C1, C2, and C3. In more complex usage, a single command matcher might match more than one command. For example, M1 matches C1 and C2, M2 matches C3, and M3 matches C4, C5, and C6. In the latter case, you would want to track the matches by updating argument values in the command matchers' updateArgs() methods.

    - -

    Here are the required and optional fields for command matcher objects:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameRequired?DescriptionExample
    commandYes(String) a simplified regular expression string that matches the command name of a command. The special regexp characters ^ and $ are automatically included at the beginning and end of the string, and therefore should not be explicitly provided.
    command: 'click.+'
    -
    command: 'rollup'
    targetYes(String) a simplified regular expression string that matches the target of a command. Same rules as for the command attribute.
    target: 'btnG'
    -
    // special regexp characters must be
    -// escaped in regexp strings. Backslashes
    -// always need to be escaped in javascript
    -// strings.
    -target: 'ui=loginPages::user\\(.+'
    -    
    valueNo(String) a simplified regular expression string that matches the value of a command. Same rules as for the command attribute.
    value: '\\d+'
    -
    value: (?:foo|bar)
    minMatchesNo(Number) the minimum number of times this command matcher must match consecutive commands for the rollup rule to match a set of commands. If unspecified, the default is 1. If maxMatches is also specified, minMatches must be less than or equal to it.
    minMatches: 2
    maxMatchesNo(Number) the maximum number of times this command matcher is allowed to match consecutive commands for the rollup rule. If unspecified, the default is 1.
    maxMatches: 2
    updateArgs()No

    (Function) updates an arguments object when a match has been found, and returns the updated arguments object. This method is used to keep track of the way in which one or more commands were matched. When a rollup rule is successfully applied, any argument name-value pairs are stored as the rollup command's value. At time of expanding the rollup command, the command's value is converted back to an arguments object, which is passed to the rollup rule's getExpandedCommands() method.

    This method must have the following method signature: updateArgs(command, args), where command is the command object that was just matched, and args is the arguments object for the current trial application of the parent rollup rule.

    // reused from above
    -updateArgs: function(command, args) {
    -    args.user = command.value;
    -    return args;
    -}
    -
    // for multiple matches
    -updateArgs: function(command, args) {
    -    if (!args.clickCount) {
    -        args.clickCount = 0;
    -    }
    -    ++args.clickCount;
    -    return args;
    -}
    -
    // another example from above (modified).
    -// If you need to parse a UI specifier,
    -// instantiate a new UISpecifier object with the
    -// locator. To do it by the book, you should
    -// first strip off the "ui=" prefix. If you just
    -// want to inspect the UI specifier's args, you
    -// can safely skip this step.
    -updateArgs: function(command, args) {
    -    var s = command.target.replace(/^ui=/, '');
    -    var uiSpecifier = new UISpecifier(s);
    -    args.term = uiSpecifier.args.term;
    -    return args;
    -}
    -
    // example from sample map file. If you're
    -// matching a rollup command that has arguments,
    -// you'll want to parse them. The easiest way
    -// to do this is with the parse_kwargs()
    -// function, which has its roots in python.
    -updateArgs: function(command, args) {
    -    var args1 = parse_kwargs(command.value);
    -    args.subtopic = args1.subtopic;
    -    return args;
    -}
    - -

    Too much mumbo jumbo?

    - -

    To see rollup rules in action in the IDE, use the included sample map with UI-Element (see instructions above in the "Including the Right Files" section), and grab the listing of 4 commands from the "Getting Motivated" section, above. Under the Source tab of the IDE, paste the commands in between the <tbody> and </tbody> tags. Now switch back to the Table tab, and click the new purple spiral button; this is the "Apply rollup rules" button. If done correctly, you should be prompted when rollup rule matches are found. Go ahead - go to the alistapart.com site and try executing the rollups!

    - -

    Release Notes

    - -

    Core-1.0

    - -
      -
    • UI-Element is now completely integrated into Selenium Core.
    • -
    • Added offset locators. Modified the delimiter to be ->.
    • -
    • getDefaultValues() can dynamically construct a list of values and assume that a document object is being passed in.
    • -
    • Arguments in UI specifier strings are presented in the same order as they are defined in the mapping file (no longer alphabetically).
    • -
    • Allow generic locators to be specified, potentially improving recording performance when there are many UI arguments.
    • -
    • Updated documentation.
    • -
    • Many other fixes.
    • -
    - -

    ui0.7

    - -
      -
    • Changed extensions id and homepage to avoid conflicting with standard Selenium IDE distribution.
    • -
    • Added rollup button.
    • -
    • Added UI-Element and Rollup panes, with beautiful colors and formatting.
    • -
    • Updated referenced version of Selenium Core to 0.8.3, and RC to 0.9.2 .
    • -
    • Added quoteForXPath() to String prototype.
    • -
    • Made XPath uppercasing much more robust. It is now backed by the ajaxslt library. Uppercasing is no longer required by UI-Element. It is used to demonstrate how XPath transformations may be used to improve XPath evaluation performance when using the javascript engine. See this thread on XPath performance. -
    • Added new rollup Selenium command and associated functionality with the RollupManager object.
    • -
    • Deprecated getXPath() and xpath in favor of getLocator() and locator in the UI-Element shorthand. Testcases now work with locator types other than XPath (implicit, CSS, etc.).
    • -
    • UI element testcases are now truly XHTML. All content is considered inner HTML of the html element, which is automatically generated. This supports the use of alternate locator types described in the above bullet.
    • -
    • Global variables introduced by UI-Element are now properties of the variable GLOBAL. You can now name your map uiMap if you wish.
    • -
    • Updated the sample map, including demonstration of implicit and CSS locators, Rollup Rules, and usage of quoteForXPath().
    • -
    • Improved auto-population of target dropdown with UI element locators and rollup names. The population logic is as follows: when a command is loaded from a file or inserted without having been recorded, all UI element locators are shown. After a command recorded or executed, only UI element locators for pagesets that match the page at time of recording or execution will be shown.
    • -
    • Made UI element testcase args mandatory. This reduces the startup time for the IDE, and improves testcase readability.
    • -
    • Updated documentation. Added this release notes section.
    • -
    - -

    Final Thoughts

    - -

    Catch UI-Element news in the Selenium category of my blog. You can also find me on the OpenQA Forums.

    - -

    - Haw-Bin Chai

    - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-element.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-element.js deleted file mode 100644 index 58709ce0..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-element.js +++ /dev/null @@ -1,1537 +0,0 @@ -//****************************************************************************** -// Globals, including constants - -var UI_GLOBAL = { - UI_PREFIX: 'ui' - , XHTML_DOCTYPE: '' - , XHTML_XMLNS: 'http://www.w3.org/1999/xhtml' -}; - -//***************************************************************************** -// Exceptions - -function UIElementException(message) -{ - this.message = message; - this.name = 'UIElementException'; -} - -function UIArgumentException(message) -{ - this.message = message; - this.name = 'UIArgumentException'; -} - -function PagesetException(message) -{ - this.message = message; - this.name = 'PagesetException'; -} - -function UISpecifierException(message) -{ - this.message = message; - this.name = 'UISpecifierException'; -} - -function CommandMatcherException(message) -{ - this.message = message; - this.name = 'CommandMatcherException'; -} - -//***************************************************************************** -// UI-Element core - -/** - * The UIElement object. This has been crafted along with UIMap to make - * specifying UI elements using JSON as simple as possible. Object construction - * will fail if 1) a proper name isn't provided, 2) a faulty args argument is - * given, or 3) getLocator() returns undefined for a valid permutation of - * default argument values. See ui-doc.html for the documentation on the - * builder syntax. - * - * @param uiElementShorthand an object whose contents conform to the - * UI-Element builder syntax. - * - * @return a new UIElement object - * @throws UIElementException - */ -function UIElement(uiElementShorthand) -{ - // a shorthand object might look like: - // - // { - // name: 'topic' - // , description: 'sidebar links to topic categories' - // , args: [ - // { - // name: 'name' - // , description: 'the name of the topic' - // , defaultValues: topLevelTopics - // } - // ] - // , getLocator: function(args) { - // return this._listXPath + - // "/a[text()=" + args.name.quoteForXPath() + "]"; - // } - // , getGenericLocator: function() { - // return this._listXPath + '/a'; - // } - // // maintain testcases for getLocator() - // , testcase1: { - // // defaultValues used if args not specified - // args: { name: 'foo' } - // , xhtml: '
    ' - // + '' - // + '
    ' - // } - // // set a local element variable - // , _listXPath: "//div[@id='topiclist']/ul/li" - // } - // - // name cannot be null or an empty string. Enforce the same requirement for - // the description. - - /** - * Recursively returns all permutations of argument-value pairs, given - * a list of argument definitions. Each argument definition will have - * a set of default values to use in generating said pairs. If an argument - * has no default values defined, it will not be included among the - * permutations. - * - * @param args a list of UIArguments - * @param opt_inDocument (optional) - * @return a list of associative arrays containing key value pairs - */ - this.permuteArgs = function(args, opt_inDocument) { - var permutations = []; - for (var i = 0; i < args.length; ++i) { - var arg = args[i]; - var defaultValues = (arguments.length > 1) - ? arg.getDefaultValues(opt_inDocument) - : arg.getDefaultValues(); - - // skip arguments for which no default values are defined - if (defaultValues.length == 0) { - continue; - } - for (var j = 0; j < defaultValues.length; ++j) { - var value = defaultValues[j]; - var nextPermutations = this.permuteArgs(args.slice(i+1)); - if (nextPermutations.length == 0) { - var permutation = {}; - permutation[arg.name] = value + ''; // make into string - permutations.push(permutation); - } - else { - for (var k = 0; k < nextPermutations.length; ++k) { - nextPermutations[k][arg.name] = value + ''; - permutations.push(nextPermutations[k]); - } - } - } - break; - } - return permutations; - } - - - - /** - * Returns a list of all testcases for this UIElement. - */ - this.getTestcases = function() - { - return this.testcases; - } - - - - /** - * Run all unit tests, stopping at the first failure, if any. Return true - * if no failures encountered, false otherwise. See the following thread - * regarding use of getElementById() on XML documents created by parsing - * text via the DOMParser: - * - * http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/2b1b82b3c53a1282/ - */ - this.test = function() - { - var parser = new DOMParser(); - var testcases = this.getTestcases(); - testcaseLoop: for (var i = 0; i < testcases.length; ++i) { - var testcase = testcases[i]; - var xhtml = UI_GLOBAL.XHTML_DOCTYPE + '' + testcase.xhtml + ''; - var doc = parser.parseFromString(xhtml, "text/xml"); - if (doc.firstChild.nodeName == 'parsererror') { - safe_alert('Error parsing XHTML in testcase "' + testcase.name - + '" for UI element "' + this.name + '": ' + "\n" - + doc.firstChild.firstChild.nodeValue); - } - - // we're no longer using the default locators when testing, because - // args is now required - var locator = parse_locator(this.getLocator(testcase.args)); - var results; - if (locator.type == 'xpath' || (locator.type == 'implicit' && - locator.string.substring(0, 2) == '//')) { - // try using the javascript xpath engine to avoid namespace - // issues. The xpath does have to be lowercase however, it - // seems. - results = eval_xpath(locator.string, doc, - { allowNativeXpath: false, returnOnFirstMatch: true }); - } - else { - // piece the locator back together - locator = (locator.type == 'implicit') - ? locator.string - : locator.type + '=' + locator.string; - results = eval_locator(locator, doc); - } - if (results.length && results[0].hasAttribute('expected-result')) { - continue testcaseLoop; - } - - // testcase failed - if (is_IDE()) { - var msg = 'Testcase "' + testcase.name - + '" failed for UI element "' + this.name + '":'; - if (!results.length) { - msg += '\n"' + locator + '" did not match any elements!'; - } - else { - msg += '\n' + results[0] + ' was not the expected result!'; - } - safe_alert(msg); - } - return false; - } - return true; - }; - - - - /** - * Creates a set of locators using permutations of default values for - * arguments used in the locator construction. The set is returned as an - * object mapping locators to key-value arguments objects containing the - * values passed to getLocator() to create the locator. - * - * @param opt_inDocument (optional) the document object of the "current" - * page when this method is invoked. Some arguments - * may have default value lists that are calculated - * based on the contents of the page. - * - * @return a list of locator strings - * @throws UIElementException - */ - this.getDefaultLocators = function(opt_inDocument) { - var defaultLocators = {}; - if (this.args.length == 0) { - defaultLocators[this.getLocator({})] = {}; - } - else { - var permutations = this.permuteArgs(this.args, opt_inDocument); - if (permutations.length != 0) { - for (var i = 0; i < permutations.length; ++i) { - var args = permutations[i]; - var locator = this.getLocator(args); - if (!locator) { - throw new UIElementException('Error in UIElement(): ' - + 'no getLocator return value for element "' + name - + '"'); - } - defaultLocators[locator] = args; - } - } - else { - // try using no arguments. If it doesn't work, fine. - try { - var locator = this.getLocator(); - defaultLocators[locator] = {}; - } - catch (e) { - safe_log('debug', e.message); - } - } - } - return defaultLocators; - }; - - - - /** - * Validate the structure of the shorthand notation this object is being - * initialized with. Throws an exception if there's a validation error. - * - * @param uiElementShorthand - * - * @throws UIElementException - */ - this.validate = function(uiElementShorthand) - { - var msg = "UIElement validation error:\n" + print_r(uiElementShorthand); - if (!uiElementShorthand.name) { - throw new UIElementException(msg + 'no name specified!'); - } - if (!uiElementShorthand.description) { - throw new UIElementException(msg + 'no description specified!'); - } - if (!uiElementShorthand.locator - && !uiElementShorthand.getLocator - && !uiElementShorthand.xpath - && !uiElementShorthand.getXPath) { - throw new UIElementException(msg + 'no locator specified!'); - } - }; - - - - this.init = function(uiElementShorthand) - { - this.validate(uiElementShorthand); - - this.name = uiElementShorthand.name; - this.description = uiElementShorthand.description; - - // construct a new getLocator() method based on the locator property, - // or use the provided function. We're deprecating the xpath property - // and getXPath() function, but still allow for them for backwards - // compatability. - if (uiElementShorthand.locator) { - this.getLocator = function(args) { - return uiElementShorthand.locator; - }; - } - else if (uiElementShorthand.getLocator) { - this.getLocator = uiElementShorthand.getLocator; - } - else if (uiElementShorthand.xpath) { - this.getLocator = function(args) { - return uiElementShorthand.xpath; - }; - } - else { - this.getLocator = uiElementShorthand.getXPath; - } - - if (uiElementShorthand.genericLocator) { - this.getGenericLocator = function() { - return uiElementShorthand.genericLocator; - }; - } - else if (uiElementShorthand.getGenericLocator) { - this.getGenericLocator = uiElementShorthand.getGenericLocator; - } - - if (uiElementShorthand.getOffsetLocator) { - this.getOffsetLocator = uiElementShorthand.getOffsetLocator; - } - - // get the testcases and local variables - this.testcases = []; - var localVars = {}; - for (var attr in uiElementShorthand) { - if (attr.match(/^testcase/)) { - var testcase = uiElementShorthand[attr]; - if (uiElementShorthand.args && - uiElementShorthand.args.length && !testcase.args) { - safe_alert('No args defined in ' + attr + ' for UI element ' - + this.name + '! Skipping testcase.'); - continue; - } - testcase.name = attr; - this.testcases.push(testcase); - } - else if (attr.match(/^_/)) { - this[attr] = uiElementShorthand[attr]; - localVars[attr] = uiElementShorthand[attr]; - } - } - - // create the arguments - this.args = [] - this.argsOrder = []; - if (uiElementShorthand.args) { - for (var i = 0; i < uiElementShorthand.args.length; ++i) { - var arg = new UIArgument(uiElementShorthand.args[i], localVars); - this.args.push(arg); - this.argsOrder.push(arg.name); - - // if an exception is thrown when invoking getDefaultValues() - // with no parameters passed in, assume the method requires an - // inDocument parameter, and thus may only be invoked at run - // time. Mark the UI element object accordingly. - try { - arg.getDefaultValues(); - } - catch (e) { - this.isDefaultLocatorConstructionDeferred = true; - } - } - - } - - if (!this.isDefaultLocatorConstructionDeferred) { - this.defaultLocators = this.getDefaultLocators(); - } - }; - - - - this.init(uiElementShorthand); -} - -// hang this off the UIElement "namespace" -UIElement.defaultOffsetLocatorStrategy = function(locatedElement, pageElement) { - if (is_ancestor(locatedElement, pageElement)) { - var offsetLocator; - var recorder = Recorder.get(locatedElement.ownerDocument.defaultView); - var builderNames = [ - 'xpath:link' - , 'xpath:img' - , 'xpath:attributes' - , 'xpath:idRelative' - , 'xpath:href' - , 'xpath:position' - ]; - for (var i = 0; i < builderNames.length; ++i) { - offsetLocator = recorder.locatorBuilders - .buildWith(builderNames[i], pageElement, locatedElement); - if (offsetLocator) { - return offsetLocator; - } - } - } - return null; -}; - - - -/** - * Constructs a UIArgument. This is mostly for checking that the values are - * valid. - * - * @param uiArgumentShorthand - * @param localVars - * - * @throws UIArgumentException - */ -function UIArgument(uiArgumentShorthand, localVars) -{ - /** - * @param uiArgumentShorthand - * - * @throws UIArgumentException - */ - this.validate = function(uiArgumentShorthand) - { - var msg = "UIArgument validation error:\n" - + print_r(uiArgumentShorthand); - - // try really hard to throw an exception! - if (!uiArgumentShorthand.name) { - throw new UIArgumentException(msg + 'no name specified!'); - } - if (!uiArgumentShorthand.description) { - throw new UIArgumentException(msg + 'no description specified!'); - } - if (!uiArgumentShorthand.defaultValues && - !uiArgumentShorthand.getDefaultValues) { - throw new UIArgumentException(msg + 'no default values specified!'); - } - }; - - - - /** - * @param uiArgumentShorthand - * @param localVars a list of local variables - */ - this.init = function(uiArgumentShorthand, localVars) - { - this.validate(uiArgumentShorthand); - - this.name = uiArgumentShorthand.name; - this.description = uiArgumentShorthand.description; - - if (uiArgumentShorthand.defaultValues) { - var defaultValues = uiArgumentShorthand.defaultValues; - this.getDefaultValues = - function() { return defaultValues; } - } - else { - this.getDefaultValues = uiArgumentShorthand.getDefaultValues; - } - - for (var name in localVars) { - this[name] = localVars[name]; - } - } - - - - this.init(uiArgumentShorthand, localVars); -} - - - -/** - * The UISpecifier constructor is overloaded. If less than three arguments are - * provided, the first argument will be considered a UI specifier string, and - * will be split out accordingly. Otherwise, the first argument will be - * considered the path. - * - * @param uiSpecifierStringOrPagesetName a UI specifier string, or the pageset - * name of the UI specifier - * @param elementName the name of the element - * @param args an object associating keys to values - * - * @return new UISpecifier object - */ -function UISpecifier(uiSpecifierStringOrPagesetName, elementName, args) -{ - /** - * Initializes this object from a UI specifier string of the form: - * - * pagesetName::elementName(arg1=value1, arg2=value2, ...) - * - * into its component parts, and returns them as an object. - * - * @return an object containing the components of the UI specifier - * @throws UISpecifierException - */ - this._initFromUISpecifierString = function(uiSpecifierString) { - var matches = /^(.*)::([^\(]+)\((.*)\)$/.exec(uiSpecifierString); - if (matches == null) { - throw new UISpecifierException('Error in ' - + 'UISpecifier._initFromUISpecifierString(): "' - + this.string + '" is not a valid UI specifier string'); - } - this.pagesetName = matches[1]; - this.elementName = matches[2]; - this.args = (matches[3]) ? parse_kwargs(matches[3]) : {}; - }; - - - - /** - * Override the toString() method to return the UI specifier string when - * evaluated in a string context. Combines the UI specifier components into - * a canonical UI specifier string and returns it. - * - * @return a UI specifier string - */ - this.toString = function() { - // empty string is acceptable for the path, but it must be defined - if (this.pagesetName == undefined) { - throw new UISpecifierException('Error in UISpecifier.toString(): "' - + this.pagesetName + '" is not a valid UI specifier pageset ' - + 'name'); - } - if (!this.elementName) { - throw new UISpecifierException('Error in UISpecifier.unparse(): "' - + this.elementName + '" is not a valid UI specifier element ' - + 'name'); - } - if (!this.args) { - throw new UISpecifierException('Error in UISpecifier.unparse(): "' - + this.args + '" are not valid UI specifier args'); - } - - uiElement = UIMap.getInstance() - .getUIElement(this.pagesetName, this.elementName); - if (uiElement != null) { - var kwargs = to_kwargs(this.args, uiElement.argsOrder); - } - else { - // probably under unit test - var kwargs = to_kwargs(this.args); - } - return this.pagesetName + '::' + this.elementName + '(' + kwargs + ')'; - }; - - - - // construct the object - if (arguments.length < 2) { - this._initFromUISpecifierString(uiSpecifierStringOrPagesetName); - } - else { - this.pagesetName = uiSpecifierStringOrPagesetName; - this.elementName = elementName; - this.args = (args) ? clone(args) : {}; - } -} - - - -function Pageset(pagesetShorthand) -{ - /** - * Returns true if the page is included in this pageset, false otherwise. - * The page is specified by a document object. - * - * @param inDocument the document object representing the page - */ - this.contains = function(inDocument) - { - var urlParts = parseUri(unescape(inDocument.location.href)); - var path = urlParts.path - .replace(/^\//, "") - .replace(/\/$/, ""); - if (!this.pathRegexp.test(path)) { - return false; - } - for (var paramName in this.paramRegexps) { - var paramRegexp = this.paramRegexps[paramName]; - if (!paramRegexp.test(urlParts.queryKey[paramName])) { - return false; - } - } - if (!this.pageContent(inDocument)) { - return false; - } - - return true; - } - - - - this.getUIElements = function() - { - var uiElements = []; - for (var uiElementName in this.uiElements) { - uiElements.push(this.uiElements[uiElementName]); - } - return uiElements; - }; - - - - /** - * Returns a list of UI specifier string stubs representing all UI elements - * for this pageset. Stubs contain all required arguments, but leave - * argument values blank. Each element stub is paired with the element's - * description. - * - * @return a list of UI specifier string stubs - */ - this.getUISpecifierStringStubs = function() - { - var stubs = []; - for (var name in this.uiElements) { - var uiElement = this.uiElements[name]; - var args = {}; - for (var i = 0; i < uiElement.args.length; ++i) { - args[uiElement.args[i].name] = ''; - } - var uiSpecifier = new UISpecifier(this.name, uiElement.name, args); - stubs.push([ - UI_GLOBAL.UI_PREFIX + '=' + uiSpecifier.toString() - , uiElement.description - ]); - } - return stubs; - } - - - - /** - * Throws an exception on validation failure. - */ - this._validate = function(pagesetShorthand) - { - var msg = "Pageset validation error:\n" - + print_r(pagesetShorthand); - if (!pagesetShorthand.name) { - throw new PagesetException(msg + 'no name specified!'); - } - if (!pagesetShorthand.description) { - throw new PagesetException(msg + 'no description specified!'); - } - if (!pagesetShorthand.paths && - !pagesetShorthand.pathRegexp && - !pagesetShorthand.pageContent) { - throw new PagesetException(msg - + 'no path, pathRegexp, or pageContent specified!'); - } - }; - - - - this.init = function(pagesetShorthand) - { - this._validate(pagesetShorthand); - - this.name = pagesetShorthand.name; - this.description = pagesetShorthand.description; - - var pathPrefixRegexp = pagesetShorthand.pathPrefix - ? RegExp.escape(pagesetShorthand.pathPrefix) : ""; - var pathRegexp = '^' + pathPrefixRegexp; - - if (pagesetShorthand.paths != undefined) { - pathRegexp += '(?:'; - for (var i = 0; i < pagesetShorthand.paths.length; ++i) { - if (i > 0) { - pathRegexp += '|'; - } - pathRegexp += RegExp.escape(pagesetShorthand.paths[i]); - } - pathRegexp += ')$'; - } - else if (pagesetShorthand.pathRegexp) { - pathRegexp += '(?:' + pagesetShorthand.pathRegexp + ')$'; - } - - this.pathRegexp = new RegExp(pathRegexp); - this.paramRegexps = {}; - for (var paramName in pagesetShorthand.paramRegexps) { - this.paramRegexps[paramName] = - new RegExp(pagesetShorthand.paramRegexps[paramName]); - } - this.pageContent = pagesetShorthand.pageContent || - function() { return true; }; - this.uiElements = {}; - }; - - - - this.init(pagesetShorthand); -} - - - -/** - * Construct the UI map object, and return it. Once the object is instantiated, - * it binds to a global variable and will not leave scope. - * - * @return new UIMap object - */ -function UIMap() -{ - // the singleton pattern, split into two parts so that "new" can still - // be used, in addition to "getInstance()" - UIMap.self = this; - - // need to attach variables directly to the Editor object in order for them - // to be in scope for Editor methods - if (is_IDE()) { - Editor.uiMap = this; - Editor.UI_PREFIX = UI_GLOBAL.UI_PREFIX; - } - - this.pagesets = new Object(); - - - - /** - * pageset[pagesetName] - * regexp - * elements[elementName] - * UIElement - */ - this.addPageset = function(pagesetShorthand) - { - try { - var pageset = new Pageset(pagesetShorthand); - } - catch (e) { - safe_alert("Could not create pageset from shorthand:\n" - + print_r(pagesetShorthand) + "\n" + e.message); - return false; - } - - if (this.pagesets[pageset.name]) { - safe_alert('Could not add pageset "' + pageset.name - + '": a pageset with that name already exists!'); - return false; - } - - this.pagesets[pageset.name] = pageset; - return true; - }; - - - - /** - * @param pagesetName - * @param uiElementShorthand a representation of a UIElement object in - * shorthand JSON. - */ - this.addElement = function(pagesetName, uiElementShorthand) - { - try { - var uiElement = new UIElement(uiElementShorthand); - } - catch (e) { - safe_alert("Could not create UI element from shorthand:\n" - + print_r(uiElementShorthand) + "\n" + e.message); - return false; - } - - // run the element's unit tests only for the IDE, and only when the - // IDE is starting. Make a rough guess as to the latter condition. - if (is_IDE() && !editor.selDebugger && !uiElement.test()) { - safe_alert('Could not add UI element "' + uiElement.name - + '": failed testcases!'); - return false; - } - - try { - this.pagesets[pagesetName].uiElements[uiElement.name] = uiElement; - } - catch (e) { - safe_alert("Could not add UI element '" + uiElement.name - + "' to pageset '" + pagesetName + "':\n" + e.message); - return false; - } - - return true; - }; - - - - /** - * Returns the pageset for a given UI specifier string. - * - * @param uiSpecifierString - * @return a pageset object - */ - this.getPageset = function(uiSpecifierString) - { - try { - var uiSpecifier = new UISpecifier(uiSpecifierString); - return this.pagesets[uiSpecifier.pagesetName]; - } - catch (e) { - return null; - } - } - - - - /** - * Returns the UIElement that a UISpecifierString or pageset and element - * pair refer to. - * - * @param pagesetNameOrUISpecifierString - * @return a UIElement, or null if none is found associated with - * uiSpecifierString - */ - this.getUIElement = function(pagesetNameOrUISpecifierString, uiElementName) - { - var pagesetName = pagesetNameOrUISpecifierString; - if (arguments.length == 1) { - var uiSpecifierString = pagesetNameOrUISpecifierString; - try { - var uiSpecifier = new UISpecifier(uiSpecifierString); - pagesetName = uiSpecifier.pagesetName; - var uiElementName = uiSpecifier.elementName; - } - catch (e) { - return null; - } - } - try { - return this.pagesets[pagesetName].uiElements[uiElementName]; - } - catch (e) { - return null; - } - }; - - - - /** - * Returns a list of pagesets that "contains" the provided page, - * represented as a document object. Containership is defined by the - * Pageset object's contain() method. - * - * @param inDocument the page to get pagesets for - * @return a list of pagesets - */ - this.getPagesetsForPage = function(inDocument) - { - var pagesets = []; - for (var pagesetName in this.pagesets) { - var pageset = this.pagesets[pagesetName]; - if (pageset.contains(inDocument)) { - pagesets.push(pageset); - } - } - return pagesets; - }; - - - - /** - * Returns a list of all pagesets. - * - * @return a list of pagesets - */ - this.getPagesets = function() - { - var pagesets = []; - for (var pagesetName in this.pagesets) { - pagesets.push(this.pagesets[pagesetName]); - } - return pagesets; - }; - - - - /** - * Returns a list of elements on a page that a given UI specifier string, - * maps to. If no elements are mapped to, returns an empty list.. - * - * @param uiSpecifierString a String that specifies a UI element with - * attendant argument values - * @param inDocument the document object the specified UI element - * appears in - * @return a potentially-empty list of elements - * specified by uiSpecifierString - */ - this.getPageElements = function(uiSpecifierString, inDocument) - { - var locator = this.getLocator(uiSpecifierString); - var results = locator ? eval_locator(locator, inDocument) : []; - return results; - }; - - - - /** - * Returns the locator string that a given UI specifier string maps to, or - * null if it cannot be mapped. - * - * @param uiSpecifierString - */ - this.getLocator = function(uiSpecifierString) - { - try { - var uiSpecifier = new UISpecifier(uiSpecifierString); - } - catch (e) { - safe_alert('Could not create UISpecifier for string "' - + uiSpecifierString + '": ' + e.message); - return null; - } - - var uiElement = this.getUIElement(uiSpecifier.pagesetName, - uiSpecifier.elementName); - try { - return uiElement.getLocator(uiSpecifier.args); - } - catch (e) { - return null; - } - } - - - - /** - * Finds and returns a UI specifier string given an element and the page - * that it appears on. - * - * @param pageElement the document element to map to a UI specifier - * @param inDocument the document the element appears in - * @return a UI specifier string, or false if one cannot be - * constructed - */ - this.getUISpecifierString = function(pageElement, inDocument) - { - var is_fuzzy_match = - BrowserBot.prototype.locateElementByUIElement.is_fuzzy_match; - var pagesets = this.getPagesetsForPage(inDocument); - for (var i = 0; i < pagesets.length; ++i) { - var pageset = pagesets[i]; - var uiElements = pageset.getUIElements(); - for (var j = 0; j < uiElements.length; ++j) { - var uiElement = uiElements[j]; - - // first test against the generic locator, if there is one. - // This should net some performance benefit when recording on - // more complicated pages. - if (uiElement.getGenericLocator) { - var passedTest = false; - var results = - eval_locator(uiElement.getGenericLocator(), inDocument); - for (var i = 0; i < results.length; ++i) { - if (results[i] == pageElement) { - passedTest = true; - break; - } - } - if (!passedTest) { - continue; - } - } - - var defaultLocators; - if (uiElement.isDefaultLocatorConstructionDeferred) { - defaultLocators = uiElement.getDefaultLocators(inDocument); - } - else { - defaultLocators = uiElement.defaultLocators; - } - - //safe_alert(print_r(uiElement.defaultLocators)); - for (var locator in defaultLocators) { - var locatedElements = eval_locator(locator, inDocument); - if (locatedElements.length) { - var locatedElement = locatedElements[0]; - } - else { - continue; - } - - // use a heuristic to determine whether the element - // specified is the "same" as the element we're matching - if (is_fuzzy_match) { - if (is_fuzzy_match(locatedElement, pageElement)) { - return UI_GLOBAL.UI_PREFIX + '=' + - new UISpecifier(pageset.name, uiElement.name, - defaultLocators[locator]); - } - } - else { - if (locatedElement == pageElement) { - return UI_GLOBAL.UI_PREFIX + '=' + - new UISpecifier(pageset.name, uiElement.name, - defaultLocators[locator]); - } - } - // ok, matching the element failed. See if an offset - // locator can complete the match. - if (uiElement.getOffsetLocator) { - for (var i = 0; i < locatedElements.length; ++i) { - var offsetLocator = uiElement - .getOffsetLocator(locatedElement, pageElement); - if (offsetLocator) { - return UI_GLOBAL.UI_PREFIX + '=' + - new UISpecifier(pageset.name, - uiElement.name, - defaultLocators[locator]) - + '->' + offsetLocator; - } - } - } - } - } - } - return false; - }; - - - - /** - * Returns a sorted list of UI specifier string stubs representing possible - * UI elements for all pagesets, paired the their descriptions. Stubs - * contain all required arguments, but leave argument values blank. - * - * @return a list of UI specifier string stubs - */ - this.getUISpecifierStringStubs = function() { - var stubs = []; - var pagesets = this.getPagesets(); - for (var i = 0; i < pagesets.length; ++i) { - stubs = stubs.concat(pagesets[i].getUISpecifierStringStubs()); - } - stubs.sort(function(a, b) { - if (a[0] < b[0]) { - return -1; - } - return a[0] == b[0] ? 0 : 1; - }); - return stubs; - } -} - -UIMap.getInstance = function() { - return (UIMap.self == null) ? new UIMap() : UIMap.self; -} - -//****************************************************************************** -// Rollups - -/** - * The Command object isn't available in the Selenium RC. We introduce an - * object with the identical constructor. In the IDE, this will be redefined, - * which is just fine. - * - * @param command - * @param target - * @param value - */ -if (typeof(Command) == 'undefined') { - function Command(command, target, value) { - this.command = command != null ? command : ''; - this.target = target != null ? target : ''; - this.value = value != null ? value : ''; - } -} - - - -/** - * A CommandMatcher object matches commands during the application of a - * RollupRule. It's specified with a shorthand format, for example: - * - * new CommandMatcher({ - * command: 'click' - * , target: 'ui=allPages::.+' - * }) - * - * which is intended to match click commands whose target is an element in the - * allPages PageSet. The matching expressions are given as regular expressions; - * in the example above, the command must be "click"; "clickAndWait" would be - * acceptable if 'click.*' were used. Here's a more complete example: - * - * new CommandMatcher({ - * command: 'type' - * , target: 'ui=loginPages::username()' - * , value: '.+_test' - * , updateArgs: function(command, args) { - * args.username = command.value; - * } - * }) - * - * Here, the command and target are fixed, but there is variability in the - * value of the command. When a command matches, the username is saved to the - * arguments object. - */ -function CommandMatcher(commandMatcherShorthand) -{ - /** - * Ensure the shorthand notation used to initialize the CommandMatcher has - * all required values. - * - * @param commandMatcherShorthand an object containing information about - * the CommandMatcher - */ - this.validate = function(commandMatcherShorthand) { - var msg = "CommandMatcher validation error:\n" - + print_r(commandMatcherShorthand); - if (!commandMatcherShorthand.command) { - throw new CommandMatcherException(msg + 'no command specified!'); - } - if (!commandMatcherShorthand.target) { - throw new CommandMatcherException(msg + 'no target specified!'); - } - if (commandMatcherShorthand.minMatches && - commandMatcherShorthand.maxMatches && - commandMatcherShorthand.minMatches > - commandMatcherShorthand.maxMatches) { - throw new CommandMatcherException(msg + 'minMatches > maxMatches!'); - } - }; - - /** - * Initialize this object. - * - * @param commandMatcherShorthand an object containing information used to - * initialize the CommandMatcher - */ - this.init = function(commandMatcherShorthand) { - this.validate(commandMatcherShorthand); - - this.command = commandMatcherShorthand.command; - this.target = commandMatcherShorthand.target; - this.value = commandMatcherShorthand.value || null; - this.minMatches = commandMatcherShorthand.minMatches || 1; - this.maxMatches = commandMatcherShorthand.maxMatches || 1; - this.updateArgs = commandMatcherShorthand.updateArgs || - function(command, args) { return args; }; - }; - - /** - * Determines whether a given command matches. Updates args by "reference" - * and returns true if it does; return false otherwise. - * - * @param command the command to attempt to match - */ - this.isMatch = function(command) { - var re = new RegExp('^' + this.command + '$'); - if (! re.test(command.command)) { - return false; - } - re = new RegExp('^' + this.target + '$'); - if (! re.test(command.target)) { - return false; - } - if (this.value != null) { - re = new RegExp('^' + this.value + '$'); - if (! re.test(command.value)) { - return false; - } - } - - // okay, the command matches - return true; - }; - - // initialization - this.init(commandMatcherShorthand); -} - - - -function RollupRuleException(message) -{ - this.message = message; - this.name = 'RollupRuleException'; -} - -function RollupRule(rollupRuleShorthand) -{ - /** - * Ensure the shorthand notation used to initialize the RollupRule has all - * required values. - * - * @param rollupRuleShorthand an object containing information about the - * RollupRule - */ - this.validate = function(rollupRuleShorthand) { - var msg = "RollupRule validation error:\n" - + print_r(rollupRuleShorthand); - if (!rollupRuleShorthand.name) { - throw new RollupRuleException(msg + 'no name specified!'); - } - if (!rollupRuleShorthand.description) { - throw new RollupRuleException(msg + 'no description specified!'); - } - // rollupRuleShorthand.args is optional - if (!rollupRuleShorthand.commandMatchers && - !rollupRuleShorthand.getRollup) { - throw new RollupRuleException(msg - + 'no command matchers specified!'); - } - if (!rollupRuleShorthand.expandedCommands && - !rollupRuleShorthand.getExpandedCommands) { - throw new RollupRuleException(msg - + 'no expanded commands specified!'); - } - - return true; - }; - - /** - * Initialize this object. - * - * @param rollupRuleShorthand an object containing information used to - * initialize the RollupRule - */ - this.init = function(rollupRuleShorthand) { - this.validate(rollupRuleShorthand); - - this.name = rollupRuleShorthand.name; - this.description = rollupRuleShorthand.description; - this.pre = rollupRuleShorthand.pre || ''; - this.post = rollupRuleShorthand.post || ''; - this.alternateCommand = rollupRuleShorthand.alternateCommand; - this.args = rollupRuleShorthand.args || []; - - if (rollupRuleShorthand.commandMatchers) { - // construct the rule from the list of CommandMatchers - this.commandMatchers = []; - var matchers = rollupRuleShorthand.commandMatchers; - for (var i = 0; i < matchers.length; ++i) { - if (matchers[i].updateArgs && this.args.length == 0) { - // enforce metadata for arguments - var msg = "RollupRule validation error:\n" - + print_r(rollupRuleShorthand) - + 'no argument metadata provided!'; - throw new RollupRuleException(msg); - } - this.commandMatchers.push(new CommandMatcher(matchers[i])); - } - - // returns false if the rollup doesn't match, or a rollup command - // if it does. If returned, the command contains the - // replacementIndexes property, which indicates which commands it - // substitutes for. - this.getRollup = function(commands) { - // this is a greedy matching algorithm - var replacementIndexes = []; - var commandMatcherQueue = this.commandMatchers; - var matchCount = 0; - var args = {}; - for (var i = 0, j = 0; i < commandMatcherQueue.length;) { - var matcher = commandMatcherQueue[i]; - if (j >= commands.length) { - // we've run out of commands! If the remaining matchers - // do not have minMatches requirements, this is a - // match. Otherwise, it's not. - if (matcher.minMatches > 0) { - return false; - } - ++i; - matchCount = 0; // unnecessary, but let's be consistent - } - else { - if (matcher.isMatch(commands[j])) { - ++matchCount; - if (matchCount == matcher.maxMatches) { - // exhausted this matcher's matches ... move on - // to next matcher - ++i; - matchCount = 0; - } - args = matcher.updateArgs(commands[j], args); - replacementIndexes.push(j); - ++j; // move on to next command - } - else { - //alert(matchCount + ', ' + matcher.minMatches); - if (matchCount < matcher.minMatches) { - return false; - } - // didn't match this time, but we've satisfied the - // requirements already ... move on to next matcher - ++i; - matchCount = 0; - // still gonna look at same command - } - } - } - - var rollup; - if (this.alternateCommand) { - rollup = new Command(this.alternateCommand, - commands[0].target, commands[0].value); - } - else { - rollup = new Command('rollup', this.name); - rollup.value = to_kwargs(args); - } - rollup.replacementIndexes = replacementIndexes; - return rollup; - }; - } - else { - this.getRollup = function(commands) { - var result = rollupRuleShorthand.getRollup(commands); - if (result) { - var rollup = new Command( - result.command - , result.target - , result.value - ); - rollup.replacementIndexes = result.replacementIndexes; - return rollup; - } - return false; - }; - } - - this.getExpandedCommands = function(kwargs) { - var commands = []; - var expandedCommands = (rollupRuleShorthand.expandedCommands - ? rollupRuleShorthand.expandedCommands - : rollupRuleShorthand.getExpandedCommands( - parse_kwargs(kwargs))); - for (var i = 0; i < expandedCommands.length; ++i) { - var command = expandedCommands[i]; - commands.push(new Command( - command.command - , command.target - , command.value - )); - } - return commands; - }; - }; - - this.init(rollupRuleShorthand); -} - - - -/** - * - */ -function RollupManager() -{ - // singleton pattern - RollupManager.self = this; - - this.init = function() - { - this.rollupRules = {}; - if (is_IDE()) { - Editor.rollupManager = this; - } - }; - - /** - * Adds a new RollupRule to the repository. Returns true on success, or - * false if the rule couldn't be added. - * - * @param rollupRuleShorthand shorthand JSON specification of the new - * RollupRule, possibly including CommandMatcher - * shorthand too. - * @return true if the rule was added successfully, - * false otherwise. - */ - this.addRollupRule = function(rollupRuleShorthand) - { - try { - var rule = new RollupRule(rollupRuleShorthand); - this.rollupRules[rule.name] = rule; - } - catch(e) { - smart_alert("Could not create RollupRule from shorthand:\n\n" - + e.message); - return false; - } - return true; - }; - - /** - * Returns a RollupRule by name. - * - * @param rollupName the name of the rule to fetch - * @return the RollupRule, or null if it isn't found. - */ - this.getRollupRule = function(rollupName) - { - return (this.rollupRules[rollupName] || null); - }; - - /** - * Returns a list of name-description pairs for use in populating the - * auto-populated target dropdown in the IDE. Rules that have an alternate - * command defined are not included in the list, as they are not bona-fide - * rollups. - * - * @return a list of name-description pairs - */ - this.getRollupRulesForDropdown = function() - { - var targets = []; - var names = keys(this.rollupRules).sort(); - for (var i = 0; i < names.length; ++i) { - var name = names[i]; - if (this.rollupRules[name].alternateCommand) { - continue; - } - targets.push([ name, this.rollupRules[name].description ]); - } - return targets; - }; - - /** - * Applies all rules to the current editor commands, asking the user in - * each case if it's okay to perform the replacement. The rules are applied - * repeatedly until there are no more matches. The algorithm should - * remember when the user has declined a replacement, and not ask to do it - * again. - * - * @return the list of commands with rollup replacements performed - */ - this.applyRollupRules = function() - { - var commands = editor.getTestCase().commands; - var blacklistedRollups = {}; - - // so long as rollups were performed, we need to keep iterating through - // the commands starting at the beginning, because further rollups may - // potentially be applied on the newly created ones. - while (true) { - var performedRollup = false; - for (var i = 0; i < commands.length; ++i) { - // iterate through commands - for (var rollupName in this.rollupRules) { - var rule = this.rollupRules[rollupName]; - var rollup = rule.getRollup(commands.slice(i)); - if (rollup) { - // since we passed in a sliced version of the commands - // array to the getRollup() method, we need to re-add - // the offset to the replacementIndexes - var k = 0; - for (; k < rollup.replacementIndexes.length; ++k) { - rollup.replacementIndexes[k] += i; - } - - // build the confirmation message - var msg = "Perform the following command rollup?\n\n"; - for (k = 0; k < rollup.replacementIndexes.length; ++k) { - var replacementIndex = rollup.replacementIndexes[k]; - var command = commands[replacementIndex]; - msg += '[' + replacementIndex + ']: '; - msg += command + "\n"; - } - msg += "\n"; - msg += rollup; - - // check against blacklisted rollups - if (blacklistedRollups[msg]) { - continue; - } - - // highlight the potentially replaced rows - for (k = 0; k < commands.length; ++k) { - var command = commands[k]; - command.result = ''; - if (rollup.replacementIndexes.indexOf(k) != -1) { - command.selectedForReplacement = true; - } - editor.view.rowUpdated(replacementIndex); - } - - // get confirmation from user - if (confirm(msg)) { - // perform rollup - var deleteRanges = []; - var replacementIndexes = rollup.replacementIndexes; - for (k = 0; k < replacementIndexes.length; ++k) { - // this is expected to be list of ranges. A - // range has a start, and a list of commands. - // The deletion only checks the length of the - // command list. - deleteRanges.push({ - start: replacementIndexes[k] - , commands: [ 1 ] - }); - } - editor.view.executeAction(new TreeView - .DeleteCommandAction(editor.view,deleteRanges)); - editor.view.insertAt(i, rollup); - - performedRollup = true; - } - else { - // cleverly remember not to try this rollup again - blacklistedRollups[msg] = true; - } - - // unhighlight - for (k = 0; k < commands.length; ++k) { - commands[k].selectedForReplacement = false; - editor.view.rowUpdated(k); - } - } - } - } - if (!performedRollup) { - break; - } - } - return commands; - }; - - this.init(); -} - -RollupManager.getInstance = function() { - return (RollupManager.self == null) - ? new RollupManager() - : RollupManager.self; -} - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-map-sample.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-map-sample.js deleted file mode 100644 index 37ab84b7..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-map-sample.js +++ /dev/null @@ -1,979 +0,0 @@ -// sample UI element mapping definition. This is for http://alistapart.com/, -// a particularly well structured site on web design principles. - - - -// in general, the map should capture structural aspects of the system, instead -// of "content". In other words, interactive elements / assertible elements -// that can be counted on to always exist should be defined here. Content - -// for example text or a link that appears in a blog entry - is always liable -// to change, and will not be fun to represent in this way. You probably don't -// want to be testing specific content anyway. - -// create the UI mapping object. THIS IS THE MOST IMPORTANT PART - DON'T FORGET -// TO DO THIS! In order for it to come into play, a user extension must -// construct the map in this way. -var myMap = new UIMap(); - - - - -// any values which may appear multiple times can be defined as variables here. -// For example, here we're enumerating a list of top level topics that will be -// used as default argument values for several UI elements. Check out how -// this variable is referenced further down. -var topics = [ - 'Code', - 'Content', - 'Culture', - 'Design', - 'Process', - 'User Science' -]; - -// map subtopics to their parent topics -var subtopics = { - 'Browsers': 'Code' - , 'CSS': 'Code' - , 'Flash': 'Code' - , 'HTML and XHTML': 'Code' - , 'Scripting': 'Code' - , 'Server Side': 'Code' - , 'XML': 'Code' - , 'Brand Arts': 'Content' - , 'Community': 'Content' - , 'Writing': 'Content' - , 'Industry': 'Culture' - , 'Politics and Money': 'Culture' - , 'State of the Web': 'Culture' - , 'Graphic Design': 'Design' - , 'User Interface Design': 'Design' - , 'Typography': 'Design' - , 'Layout': 'Design' - , 'Business': 'Process' - , 'Creativity': 'Process' - , 'Project Management and Workflow': 'Process' - , 'Accessibility': 'User Science' - , 'Information Architecture': 'User Science' - , 'Usability': 'User Science' -}; - - - -// define UI elements common for all pages. This regular expression does the -// trick. '^' is automatically prepended, and '$' is automatically postpended. -// Please note that because the regular expression is being represented as a -// string, all backslashes must be escaped with an additional backslash. Also -// note that the URL being matched will always have any trailing forward slash -// stripped. -myMap.addPageset({ - name: 'allPages' - , description: 'all alistapart.com pages' - , pathRegexp: '.*' -}); -myMap.addElement('allPages', { - name: 'masthead' - // the description should be short and to the point, usually no longer than - // a single line - , description: 'top level image link to site homepage' - // make sure the function returns the XPath ... it's easy to leave out the - // "return" statement by accident! - , locator: "xpath=//*[@id='masthead']/a/img" - , testcase1: { - xhtml: '

    ' - } -}); -myMap.addElement('allPages', { - // be VERY CAREFUL to include commas in the correct place. Missing commas - // and extra commas can cause lots of headaches when debugging map - // definition files!!! - name: 'current_issue' - , description: 'top level link to issue currently being browsed' - , locator: "//div[@id='ish']/a" - , testcase1: { - xhtml: '
    ' - } -}); -myMap.addElement('allPages', { - name: 'section' - , description: 'top level link to articles section' - , args: [ - { - name: 'section' - , description: 'the name of the section' - , defaultValues: [ - 'articles' - , 'topics' - , 'about' - , 'contact' - , 'contribute' - , 'feed' - ] - } - ] - // getXPath has been deprecated by getLocator, but verify backward - // compatability here - , getXPath: function(args) { - return "//li[@id=" + args.section.quoteForXPath() + "]/a"; - } - , testcase1: { - args: { section: 'feed' } - , xhtml: '
    ' - } -}); -myMap.addElement('allPages', { - name: 'search_box' - , description: 'site search input field' - // xpath has been deprecated by locator, but verify backward compatability - , xpath: "//input[@id='search']" - , testcase1: { - xhtml: '' - } -}); -myMap.addElement('allPages', { - name: 'search_discussions' - , description: 'site search include discussions checkbox' - , locator: 'incdisc' - , testcase1: { - xhtml: '' - } -}); -myMap.addElement('allPages', { - name: 'search_submit' - , description: 'site search submission button' - , locator: 'submit' - , testcase1: { - xhtml: '' - } -}); -myMap.addElement('allPages', { - name: 'topics' - , description: 'sidebar links to topic categories' - , args: [ - { - name: 'topic' - , description: 'the name of the topic' - , defaultValues: topics - } - ] - , getLocator: function(args) { - return "//div[@id='topiclist']/ul/li" + - "/a[text()=" + args.topic.quoteForXPath() + "]"; - } - , testcase1: { - args: { topic: 'foo' } - , xhtml: '
    ' - } -}); -myMap.addElement('allPages', { - name: 'copyright' - , description: 'footer link to copyright page' - , getLocator: function(args) { return "//span[@class='copyright']/a"; } - , testcase1: { - xhtml: '' - } -}); - - - -// define UI elements for the homepage, i.e. "http://alistapart.com/", and -// magazine issue pages, i.e. "http://alistapart.com/issues/234". -myMap.addPageset({ - name: 'issuePages' - , description: 'pages including magazine issues' - , pathRegexp: '(issues/.+)?' -}); -myMap.addElement('issuePages', { - name: 'article' - , description: 'front or issue page link to article' - , args: [ - { - name: 'index' - , description: 'the index of the article' - // an array of default values for the argument. A default - // value is one that is passed to the getXPath() method of - // the container UIElement object when trying to build an - // element locator. - // - // range() may be used to count easily. Remember though that - // the ending value does not include the right extreme; for - // example range(1, 5) counts from 1 to 4 only. - , defaultValues: range(1, 5) - } - ] - , getLocator: function(args) { - return "//div[@class='item'][" + args.index + "]/h4/a"; - } -}); -myMap.addElement('issuePages', { - name: 'author' - , description: 'article author link' - , args: [ - { - name: 'index' - , description: 'the index of the author, by article' - , defaultValues: range(1, 5) - } - ] - , getLocator: function(args) { - return "//div[@class='item'][" + args.index + "]/h5/a"; - } -}); -myMap.addElement('issuePages', { - name: 'store' - , description: 'alistapart.com store link' - , locator: "//ul[@id='banners']/li/a[@title='ALA Store']/img" -}); -myMap.addElement('issuePages', { - name: 'special_article' - , description: "editor's choice article link" - , locator: "//div[@id='choice']/h4/a" -}); -myMap.addElement('issuePages', { - name: 'special_author' - , description: "author link of editor's choice article" - , locator: "//div[@id='choice']/h5/a" -}); - - - -// define UI elements for the articles page, i.e. -// "http://alistapart.com/articles" -myMap.addPageset({ - name: 'articleListPages' - , description: 'page with article listings' - , paths: [ 'articles' ] -}); -myMap.addElement('articleListPages', { - name: 'issue' - , description: 'link to issue' - , args: [ - { - name: 'index' - , description: 'the index of the issue on the page' - , defaultValues: range(1, 10) - } - ] - , getLocator: function(args) { - return "//h2[@class='ishinfo'][" + args.index + ']/a'; - } - , genericLocator: "//h2[@class='ishinfo']/a" -}); -myMap.addElement('articleListPages', { - name: 'article' - , description: 'link to article, by issue and article number' - , args: [ - { - name: 'issue_index' - , description: "the index of the article's issue on the page; " - + 'typically five per page' - , defaultValues: range(1, 6) - } - , { - name: 'article_index' - , description: 'the index of the article within the issue; ' - + 'typically two per issue' - , defaultValues: range(1, 5) - } - ] - , getLocator: function(args) { - var xpath = "//h2[@class='ishinfo'][" + (args.issue_index || 1) + ']' - + "/following-sibling::div[@class='item']" - + '[' + (args.article_index || 1) + "]/h3[@class='title']/a"; - return xpath; - } - , genericLocator: "//h2[@class='ishinfo']" - + "/following-sibling::div[@class='item']/h3[@class='title']/a" -}); -myMap.addElement('articleListPages', { - name: 'author' - , description: 'article author link, by issue and article' - , args: [ - { - name: 'issue_index' - , description: "the index of the article's issue on the page; \ -typically five per page" - , defaultValues: range(1, 6) - } - , { - name: 'article_index' - , description: "the index of the article within the issue; \ -typically two articles per issue" - , defaultValues: range(1, 3) - } - ] - // this XPath uses the "following-sibling" axis. The div elements for - // the articles in an issue are not children, but siblings of the h2 - // element identifying the article. - , getLocator: function(args) { - var xpath = "//h2[@class='ishinfo'][" + (args.issue_index || 1) + ']' - + "/following-sibling::div[@class='item']" - + '[' + (args.article_index || 1) + "]/h4[@class='byline']/a"; - return xpath; - } - , genericLocator: "//h2[@class='ishinfo']" - + "/following-sibling::div[@class='item']/h4[@class='byline']/a" -}); -myMap.addElement('articleListPages', { - name: 'next_page' - , description: 'link to next page of articles (older)' - , locator: "//a[contains(text(),'Next page')]" -}); -myMap.addElement('articleListPages', { - name: 'previous_page' - , description: 'link to previous page of articles (newer)' - , locator: "//a[contains(text(),'Previous page')]" -}); - - - -// define UI elements for specific article pages, i.e. -// "http://alistapart.com/articles/culturalprobe" -myMap.addPageset({ - name: 'articlePages' - , description: 'pages for actual articles' - , pathRegexp: 'articles/.+' -}); -myMap.addElement('articlePages', { - name: 'title' - , description: 'article title loop-link' - , locator: "//div[@id='content']/h1[@class='title']/a" -}); -myMap.addElement('articlePages', { - name: 'author' - , description: 'article author link' - , locator: "//div[@id='content']/h3[@class='byline']/a" -}); -myMap.addElement('articlePages', { - name: 'article_topics' - , description: 'links to topics under which article is published, before \ -article content' - , args: [ - { - name: 'topic' - , description: 'the name of the topic' - , defaultValues: keys(subtopics) - } - ] - , getLocator: function(args) { - return "//ul[@id='metastuff']/li/a" - + "[@title=" + args.topic.quoteForXPath() + "]"; - } -}); -myMap.addElement('articlePages', { - name: 'discuss' - , description: 'link to article discussion area, before article content' - , locator: "//ul[@id='metastuff']/li[@class='discuss']/p/a" -}); -myMap.addElement('articlePages', { - name: 'related_topics' - , description: 'links to topics under which article is published, after \ -article content' - , args: [ - { - name: 'topic' - , description: 'the name of the topic' - , defaultValues: keys(subtopics) - } - ] - , getLocator: function(args) { - return "//div[@id='learnmore']/p/a" - + "[@title=" + args.topic.quoteForXPath() + "]"; - } -}); -myMap.addElement('articlePages', { - name: 'join_discussion' - , description: 'link to article discussion area, after article content' - , locator: "//div[@class='discuss']/p/a" -}); - - - -myMap.addPageset({ - name: 'topicListingPages' - , description: 'top level listing of topics' - , paths: [ 'topics' ] -}); -myMap.addElement('topicListingPages', { - name: 'topic' - , description: 'link to topic category' - , args: [ - { - name: 'topic' - , description: 'the name of the topic' - , defaultValues: topics - } - ] - , getLocator: function(args) { - return "//div[@id='content']/h2/a" - + "[text()=" + args.topic.quoteForXPath() + "]"; - } -}); -myMap.addElement('topicListingPages', { - name: 'subtopic' - , description: 'link to subtopic category' - , args: [ - { - name: 'subtopic' - , description: 'the name of the subtopic' - , defaultValues: keys(subtopics) - } - ] - , getLocator: function(args) { - return "//div[@id='content']" + - "/descendant::a[text()=" + args.subtopic.quoteForXPath() + "]"; - } -}); - -// the following few subtopic page UI elements are very similar. Define UI -// elements for the code page, which is a subpage under topics, i.e. -// "http://alistapart.com/topics/code/" -myMap.addPageset({ - name: 'subtopicListingPages' - , description: 'pages listing subtopics' - , pathPrefix: 'topics/' - , paths: [ - 'code' - , 'content' - , 'culture' - , 'design' - , 'process' - , 'userscience' - ] -}); -myMap.addElement('subtopicListingPages', { - name: 'subtopic' - , description: 'link to a subtopic category' - , args: [ - { - name: 'subtopic' - , description: 'the name of the subtopic' - , defaultValues: keys(subtopics) - } - ] - , getLocator: function(args) { - return "//div[@id='content']/h2" + - "/a[text()=" + args.subtopic.quoteForXPath() + "]"; - } -}); - - - -// subtopic articles page -myMap.addPageset({ - name: 'subtopicArticleListingPages' - , description: 'pages listing the articles for a given subtopic' - , pathRegexp: 'topics/[^/]+/.+' -}); -myMap.addElement('subtopicArticleListingPages', { - name: 'article' - , description: 'link to a subtopic article' - , args: [ - { - name: 'index' - , description: 'the index of the article' - , defaultValues: range(1, 51) // the range seems unlimited ... - } - ] - , getLocator: function(args) { - return "//div[@id='content']/div[@class='item']" - + "[" + args.index + "]/h3/a"; - } - , testcase1: { - args: { index: 2 } - , xhtml: '
    ' - } -}); -myMap.addElement('subtopicArticleListingPages', { - name: 'author' - , description: "link to a subtopic article author's page" - , args: [ - { - name: 'article_index' - , description: 'the index of the authored article' - , defaultValues: range(1, 51) - } - , { - name: 'author_index' - , description: 'the index of the author when there are multiple' - , defaultValues: range(1, 4) - } - ] - , getLocator: function(args) { - return "//div[@id='content']/div[@class='item'][" + - args.article_index + "]/h4/a[" + - (args.author_index ? args.author_index : '1') + ']'; - } -}); -myMap.addElement('subtopicArticleListingPages', { - name: 'issue' - , description: 'link to issue a subtopic article appears in' - , args: [ - { - name: 'index' - , description: 'the index of the subtopic article' - , defaultValues: range(1, 51) - } - ] - , getLocator: function(args) { - return "//div[@id='content']/div[@class='item']" - + "[" + args.index + "]/h5/a"; - } -}); - - - -myMap.addPageset({ - name: 'aboutPages' - , description: 'the website about page' - , paths: [ 'about' ] -}); -myMap.addElement('aboutPages', { - name: 'crew' - , description: 'link to site crew member bio or personal website' - , args: [ - { - name: 'role' - , description: 'the role of the crew member' - , defaultValues: [ - 'ALA Crew' - , 'Support' - , 'Emeritus' - ] - } - , { - name: 'role_index' - , description: 'the index of the member within the role' - , defaultValues: range(1, 20) - } - , { - name: 'member_index' - , description: 'the index of the member within the role title' - , defaultValues: range(1, 5) - } - ] - , getLocator: function(args) { - // the first role is kind of funky, and requires a conditional to - // build the XPath correctly. Its header looks like this: - // - //

    - // ALA 4.0 CREW - //

    - // - // This kind of complexity is a little daunting, but you can see - // how the format can handle it relatively easily and concisely. - if (args.role == 'ALA Crew') { - var selector = "descendant::text()='CREW'"; - } - else { - var selector = "text()=" + args.role.quoteForXPath(); - } - var xpath = - "//div[@id='secondary']/h3[" + selector + ']' + - "/following-sibling::dl/dt[" + (args.role_index || 1) + ']' + - '/a[' + (args.member_index || '1') + ']'; - return xpath; - } -}); - - - -myMap.addPageset({ - name: 'searchResultsPages' - , description: 'pages listing search results' - , paths: [ 'search' ] -}); -myMap.addElement('searchResultsPages', { - name: 'result_link' - , description: 'search result link' - , args: [ - { - name: 'index' - , description: 'the index of the search result' - , defaultValues: range(1, 11) - } - ] - , getLocator: function(args) { - return "//div[@id='content']/ul[" + args.index + ']/li/h3/a'; - } -}); -myMap.addElement('searchResultsPages', { - name: 'more_results_link' - , description: 'next or previous results link at top or bottom of page' - , args: [ - { - name: 'direction' - , description: 'next or previous results page' - // demonstrate a method which acquires default values from the - // document object. Such default values may contain EITHER commas - // OR equals signs, but NOT BOTH. - , getDefaultValues: function(inDocument) { - var defaultValues = []; - var divs = inDocument.getElementsByTagName('div'); - for (var i = 0; i < divs.length; ++i) { - if (divs[i].className == 'pages') { - break; - } - } - var links = divs[i].getElementsByTagName('a'); - for (i = 0; i < links.length; ++i) { - defaultValues.push(links[i].innerHTML - .replace(/^\xab\s*/, "") - .replace(/\s*\bb$/, "") - .replace(/\s*\d+$/, "")); - } - return defaultValues; - } - } - , { - name: 'position' - , description: 'position of the link' - , defaultValues: ['top', 'bottom'] - } - ] - , getLocator: function(args) { - return "//div[@id='content']/div[@class='pages'][" - + (args.position == 'top' ? '1' : '2') + ']' - + "/a[contains(text(), " - + (args.direction ? args.direction.quoteForXPath() : undefined) - + ")]"; - } -}); - - - -myMap.addPageset({ - name: 'commentsPages' - , description: 'pages listing comments made to an article' - , pathRegexp: 'comments/.+' -}); -myMap.addElement('commentsPages', { - name: 'article_link' - , description: 'link back to the original article' - , locator: "//div[@id='content']/h1[@class='title']/a" -}); -myMap.addElement('commentsPages', { - name: 'comment_link' - , description: 'same-page link to comment' - , args: [ - { - name: 'index' - , description: 'the index of the comment' - , defaultValues: range(1, 11) - } - ] - , getLocator: function(args) { - return "//div[@class='content']/div[contains(@class, 'comment')]" + - '[' + args.index + ']/h4/a[2]'; - } -}); -myMap.addElement('commentsPages', { - name: 'paging_link' - , description: 'links to more pages of comments' - , args: [ - { - name: 'dest' - , description: 'the destination page' - , defaultValues: ['next', 'prev'].concat(range(1, 16)) - } - , { - name: 'position' - , description: 'position of the link' - , defaultValues: ['top', 'bottom'] - } - ] - , getLocator: function(args) { - var dest = args.dest; - var xpath = "//div[@id='content']/div[@class='pages']" + - '[' + (args.position == 'top' ? '1' : '2') + ']/p'; - if (dest == 'next' || dest == 'prev') { - xpath += "/a[contains(text(), " + dest.quoteForXPath() + ")]"; - } - else { - xpath += "/a[text()=" + dest.quoteForXPath() + "]"; - } - return xpath; - } -}); - - - -myMap.addPageset({ - name: 'authorPages' - , description: 'personal pages for each author' - , pathRegexp: 'authors/[a-z]/.+' -}); -myMap.addElement('authorPages', { - name: 'article' - , description: "link to article written by this author.\n" - + 'This description has a line break.' - , args: [ - { - name: 'index' - , description: 'index of the article on the page' - , defaultValues: range(1, 11) - } - ] - , getLocator: function(args) { - var index = args.index; - // try out the CSS locator! - //return "//h4[@class='title'][" + index + "]/a"; - return 'css=h4.title:nth-child(' + index + ') > a'; - } - , testcase1: { - args: { index: '2' } - , xhtml: '

    ' - + '

    ' - } -}); - - - -// test the offset locator. Something like the following can be recorded: -// ui=qaPages::content()//a[contains(text(),'May I quote from your articles?')] -myMap.addPageset({ - name: 'qaPages' - , description: 'question and answer pages' - , pathRegexp: 'qa' -}); -myMap.addElement('qaPages', { - name: 'content' - , description: 'the content pane containing the q&a entries' - , locator: "//div[@id='content' and " - + "child::h1[text()='Questions and Answers']]" - , getOffsetLocator: UIElement.defaultOffsetLocatorStrategy -}); -myMap.addElement('qaPages', { - name: 'last_updated' - , description: 'displays the last update date' - // demonstrate calling getLocator() for another UI element within a - // getLocator(). The former must have already been added to the map. And - // obviously, you can't randomly combine different locator types! - , locator: myMap.getUIElement('qaPages', 'content').getLocator() + '/p/em' -}); - - - -//****************************************************************************** - -var myRollupManager = new RollupManager(); - -// though the description element is required, its content is free form. You -// might want to create a documentation policy as given below, where the pre- -// and post-conditions of the rollup are spelled out. -// -// To take advantage of a "heredoc" like syntax for longer descriptions, -// add a backslash to the end of the current line and continue the string on -// the next line. -myRollupManager.addRollupRule({ - name: 'navigate_to_subtopic_article_listing' - , description: 'drill down to the listing of articles for a given subtopic \ -from the section menu, then the topic itself.' - , pre: 'current page contains the section menu (most pages should)' - , post: 'navigated to the page listing all articles for a given subtopic' - , args: [ - { - name: 'subtopic' - , description: 'the subtopic whose article listing to navigate to' - , exampleValues: keys(subtopics) - } - ] - , commandMatchers: [ - { - command: 'clickAndWait' - , target: 'ui=allPages::section\\(section=topics\\)' - // must escape parentheses in the the above target, since the - // string is being used as a regular expression. Again, backslashes - // in strings must be escaped too. - } - , { - command: 'clickAndWait' - , target: 'ui=topicListingPages::topic\\(.+' - } - , { - command: 'clickAndWait' - , target: 'ui=subtopicListingPages::subtopic\\(.+' - , updateArgs: function(command, args) { - // don't bother stripping the "ui=" prefix from the locator - // here; we're just using UISpecifier to parse the args out - var uiSpecifier = new UISpecifier(command.target); - args.subtopic = uiSpecifier.args.subtopic; - return args; - } - } - ] - , getExpandedCommands: function(args) { - var commands = []; - var topic = subtopics[args.subtopic]; - var subtopic = args.subtopic; - commands.push({ - command: 'clickAndWait' - , target: 'ui=allPages::section(section=topics)' - }); - commands.push({ - command: 'clickAndWait' - , target: 'ui=topicListingPages::topic(topic=' + topic + ')' - }); - commands.push({ - command: 'clickAndWait' - , target: 'ui=subtopicListingPages::subtopic(subtopic=' + subtopic - + ')' - }); - commands.push({ - command: 'verifyLocation' - , target: 'regexp:.+/topics/.+/.+' - }); - return commands; - } -}); - - - -myRollupManager.addRollupRule({ - name: 'replace_click_with_clickAndWait' - , description: 'replaces commands where a click was detected with \ -clickAndWait instead' - , alternateCommand: 'clickAndWait' - , commandMatchers: [ - { - command: 'click' - , target: 'ui=subtopicArticleListingPages::article\\(.+' - } - ] - , expandedCommands: [] -}); - - - -myRollupManager.addRollupRule({ - name: 'navigate_to_subtopic_article' - , description: 'navigate to an article listed under a subtopic.' - , pre: 'current page contains the section menu (most pages should)' - , post: 'navigated to an article page' - , args: [ - { - name: 'subtopic' - , description: 'the subtopic whose article listing to navigate to' - , exampleValues: keys(subtopics) - } - , { - name: 'index' - , description: 'the index of the article in the listing' - , exampleValues: range(1, 11) - } - ] - , commandMatchers: [ - { - command: 'rollup' - , target: 'navigate_to_subtopic_article_listing' - , value: 'subtopic\\s*=.+' - , updateArgs: function(command, args) { - var args1 = parse_kwargs(command.value); - args.subtopic = args1.subtopic; - return args; - } - } - , { - command: 'clickAndWait' - , target: 'ui=subtopicArticleListingPages::article\\(.+' - , updateArgs: function(command, args) { - var uiSpecifier = new UISpecifier(command.target); - args.index = uiSpecifier.args.index; - return args; - } - } - ] - /* - // this is pretty much equivalent to the commandMatchers immediately above. - // Seems more verbose and less expressive, doesn't it? But sometimes you - // might prefer the flexibility of a function. - , getRollup: function(commands) { - if (commands.length >= 2) { - command1 = commands[0]; - command2 = commands[1]; - var args1 = parse_kwargs(command1.value); - try { - var uiSpecifier = new UISpecifier(command2.target - .replace(/^ui=/, '')); - } - catch (e) { - return false; - } - if (command1.command == 'rollup' && - command1.target == 'navigate_to_subtopic_article_listing' && - args1.subtopic && - command2.command == 'clickAndWait' && - uiSpecifier.pagesetName == 'subtopicArticleListingPages' && - uiSpecifier.elementName == 'article') { - var args = { - subtopic: args1.subtopic - , index: uiSpecifier.args.index - }; - return { - command: 'rollup' - , target: this.name - , value: to_kwargs(args) - , replacementIndexes: [ 0, 1 ] - }; - } - } - return false; - } - */ - , getExpandedCommands: function(args) { - var commands = []; - commands.push({ - command: 'rollup' - , target: 'navigate_to_subtopic_article_listing' - , value: to_kwargs({ subtopic: args.subtopic }) - }); - var uiSpecifier = new UISpecifier( - 'subtopicArticleListingPages' - , 'article' - , { index: args.index }); - commands.push({ - command: 'clickAndWait' - , target: 'ui=' + uiSpecifier.toString() - }); - commands.push({ - command: 'verifyLocation' - , target: 'regexp:.+/articles/.+' - }); - return commands; - } -}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js deleted file mode 100644 index dde72cac..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js +++ /dev/null @@ -1,6 +0,0 @@ -// All get* methods on the Selenium prototype result in -// store, assert, assertNot, verify, verifyNot, waitFor, and waitForNot commands. -// Will result in support for storeContextCount, assertContextCount, etc. -Selenium.prototype.getContextCount = function() { - return this.browserbot.getCurrentWindow().$('.context').size(); -}; diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js.sample b/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js.sample deleted file mode 100644 index 0f0ca840..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js.sample +++ /dev/null @@ -1,75 +0,0 @@ -/* - * By default, Selenium looks for a file called "user-extensions.js", and loads and javascript - * code found in that file. This file is a sample of what that file could look like. - * - * user-extensions.js provides a convenient location for adding extensions to Selenium, like - * new actions, checks and locator-strategies. - * By default, this file does not exist. Users can create this file and place their extension code - * in this common location, removing the need to modify the Selenium sources, and hopefully assisting - * with the upgrade process. - * - * You can find contributed extensions at http://wiki.openqa.org/display/SEL/Contributed%20User-Extensions - */ - -// The following examples try to give an indication of how Selenium can be extended with javascript. - -// All do* methods on the Selenium prototype are added as actions. -// Eg add a typeRepeated action to Selenium, which types the text twice into a text box. -// The typeTwiceAndWait command will be available automatically -Selenium.prototype.doTypeRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to type - var valueToType = text + text; - - // Replace the element text with the new text - this.page().replaceText(element, valueToType); -}; - -// All assert* methods on the Selenium prototype are added as checks. -// Eg add a assertValueRepeated check, that makes sure that the element value -// consists of the supplied text repeated. -// The verify version will be available automatically. -Selenium.prototype.assertValueRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to verify - var expectedValue = text + text; - - // Get the actual element value - var actualValue = element.value; - - // Make sure the actual value matches the expected - Assert.matches(expectedValue, actualValue); -}; - -// All get* methods on the Selenium prototype result in -// store, assert, assertNot, verify, verifyNot, waitFor, and waitForNot commands. -// E.g. add a getTextLength method that returns the length of the text -// of a specified element. -// Will result in support for storeTextLength, assertTextLength, etc. -Selenium.prototype.getTextLength = function(locator) { - return this.getText(locator).length; -}; - -// All locateElementBy* methods are added as locator-strategies. -// Eg add a "valuerepeated=" locator, that finds the first element with the supplied value, repeated. -// The "inDocument" is a the document you are searching. -PageBot.prototype.locateElementByValueRepeated = function(text, inDocument) { - // Create the text to search for - var expectedValue = text + text; - - // Loop through all elements, looking for ones that have a value === our expected value - var allElements = inDocument.getElementsByTagName("*"); - for (var i = 0; i < allElements.length; i++) { - var testElement = allElements[i]; - if (testElement.value && testElement.value === expectedValue) { - return testElement; - } - } - return null; -}; - - diff --git a/vendor/plugins/selenium-on-rails/selenium-core/scripts/xmlextras.js b/vendor/plugins/selenium-on-rails/selenium-core/scripts/xmlextras.js deleted file mode 100644 index 267aa058..00000000 --- a/vendor/plugins/selenium-on-rails/selenium-core/scripts/xmlextras.js +++ /dev/null @@ -1,153 +0,0 @@ -// This is a third party JavaScript library from -// http://webfx.eae.net/dhtml/xmlextras/xmlextras.html -// i.e. This has not been written by ThoughtWorks. - -// - - - -
    Foo
    Bar
    -EOS - end - - def teardown - FileUtils.rm_rf @result_dir - end - - def test_record_with_result - @controller.instance_variable_set(:@result_dir, @result_dir) - - post :record, :suite => @suite, "testTable.1" => "
    ", "testTable.2" => "
    " - - cur_result_dir = File.join(@result_dir, "default") - assert File.directory?(cur_result_dir) - assert_equal ["blank.html", "index.html", "suite.html", "test1.html", "test2.html"], - Dir.glob("#{cur_result_dir}/*.html").map{|path| File.basename(path)}.sort - - expected = < - - - - - - - -
    Foo
    Bar
    - -EOS - assert_equal expected, File.read("#{cur_result_dir}/suite.html") - end - - def test_result_hash - post :record, :suite => @suite, "testTable.1" => "
    ", "testTable.2" => "
    ", - :result => 'Failed', :numTestFailures => "906", :numTestPasses => "1079", :numCommandFailures => '1027', - :numCommandErrors => '57', :numCommandPasses => '3', :totalTime => "A long time" - - assert_equal 'Failed', assigns['result']['result'] - assert_equal '906', assigns['result']['numTestFailures'] - assert_equal '1079', assigns['result']['numTestPasses'] - assert_equal '1027', assigns['result']['numCommandFailures'] - assert_equal '57', assigns['result']['numCommandErrors'] - assert_equal '3', assigns['result']['numCommandPasses'] - assert_equal 'A long time', assigns['result']['totalTime'] - end -end diff --git a/vendor/plugins/selenium-on-rails/test/selenium_on_rails_config_test.rb b/vendor/plugins/selenium-on-rails/test/selenium_on_rails_config_test.rb deleted file mode 100644 index 61f80834..00000000 --- a/vendor/plugins/selenium-on-rails/test/selenium_on_rails_config_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' -require 'mocha' - -class SeleniumOnRailsConfig - def self.reset_config - @@configs = nil - end -end - -class SeleniumOnRailsConfigTest < Test::Unit::TestCase - - def setup - SeleniumOnRailsConfig.reset_config - @selenium_file = File.join(RAILS_ROOT, 'config', 'selenium.yml') - @config_file = File.expand_path(File.dirname(__FILE__) + '/../config.yml') - @selenium_content = File.read(File.dirname(__FILE__) + '/fixtures/selenium.yml') - @config_content = File.read(File.dirname(__FILE__) + '/fixtures/config.yml') - end - - def test_get_selenium_yaml - File.expects(:exist?).with(@selenium_file).returns(true) - IO.expects(:read).with(@selenium_file).returns(@selenium_content) - IO.expects(:read).with(@config_file).never - IO.expects(:exist?).with(@config_file).never - - assert_equal ["test_cache"], SeleniumOnRailsConfig.get(:environments) - assert_equal({"firefox"=>"script/openfirefox"}, SeleniumOnRailsConfig.get(:browsers)) - end - - def test_get_when_config_yml_exists_but_selenium_yaml_not - File.expects(:exist?).with(@selenium_file).returns(false) - File.expects(:exist?).with(@config_file).returns(true) - IO.expects(:read).with(@config_file).returns(@config_content) - IO.expects(:read).with(@selenium_file).never - - assert_equal ["test"], SeleniumOnRailsConfig.get(:environments) - expected_config = {"safari"=>"/Applications/Safari.app/Contents/MacOS/Safari", - "firefox"=>"/Applications/Firefox.app/Contents/MacOS/firefox-bin"} - - assert_equal(expected_config, SeleniumOnRailsConfig.get(:browsers)) - end - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test/selenium_support_test.rb b/vendor/plugins/selenium-on-rails/test/selenium_support_test.rb deleted file mode 100644 index 5fb469e4..00000000 --- a/vendor/plugins/selenium-on-rails/test/selenium_support_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' - -class SeleniumSupportTest < Test::Unit::TestCase - def setup - @controller = SeleniumController.new - @controller.extend(SeleniumOnRails::PathsTestHelper) - ActionController::Routing::Routes.draw - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - def test_route - get :support_file, :filename => 'TestRunner.html' #initialize the controller - assert_equal 'http://test.host/selenium/TestRunner.html', - @controller.url_for(:controller => 'selenium', :action => 'support_file', :filename => 'TestRunner.html') - end - - def test_test_runner_existance - get :support_file, :filename => 'TestRunner.html' - assert_response :success - assert @response.body.include?('Selenium') - end - - def test_default_file - get :support_file, :filename => '' - assert_redirected_to :filename => 'TestRunner.html', :test => 'tests' - end - - def test_missing_file - get :support_file, :filename => 'missing.html' - assert_response 404 - assert_equal 'Not found', @response.body - end - -end diff --git a/vendor/plugins/selenium-on-rails/test/setup_test.rb b/vendor/plugins/selenium-on-rails/test/setup_test.rb deleted file mode 100644 index c24c4869..00000000 --- a/vendor/plugins/selenium-on-rails/test/setup_test.rb +++ /dev/null @@ -1,31 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' -require 'mocha' -RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + "/") - -class SetupTest < Test::Unit::TestCase - def setup - @controller = SeleniumController.new - @controller.extend(SeleniumOnRails::PathsTestHelper) - SeleniumController.any_instance.stubs(:clear_tables).returns([]) - SeleniumController.any_instance.stubs(:layout_path).returns(false) - ActionController::Routing::Routes.draw - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - def test_session_reset - @request.session['key'] = 'value' - get :setup - assert_nil session['key'] - assert_response :success - assert_tag :content => 'The session is wiped clean.' - end - - def test_session_no_reset - @request.session['key'] = 'value' - get :setup, :keep_session => true - assert_equal 'value', session['key'] - assert_response :success - assert_no_tag :content => 'The session is wiped clean.' - end -end diff --git a/vendor/plugins/selenium-on-rails/test/suite_renderer_test.rb b/vendor/plugins/selenium-on-rails/test/suite_renderer_test.rb deleted file mode 100644 index 92f9c2f3..00000000 --- a/vendor/plugins/selenium-on-rails/test/suite_renderer_test.rb +++ /dev/null @@ -1,109 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' - -class SuiteRendererTest < Test::Unit::TestCase - def setup - @controller = SeleniumController.new - @controller.extend(SeleniumOnRails::PathsTestHelper) - ActionController::Routing::Routes.draw - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @controller.layout_override =<test layout -@content_for_layout - -END - end - - def test_empty_suite - get :test_file, :testname => 'empty_suite' - - assert_response :success - assert_tag :tag => "title", :content => "test layout" - assert_tag :tag => "script", :attributes => {:type => "text/javascript"} - assert_tag :tag => "select", :attributes => {:onchange => "openSuite(this)"}, - :descendant => {:tag => "option", :attributes => {:value => "header"}, :content => "Suites:"}, - :descendant => {:tag => "option", :attributes => {:value => ""}, :content => ".."} - - assert_tag :tag => "table", - :descendant => {:tag => "th", :content => "Empty suite"} - end - - def test_root_suite - _test_root_suite '' - end - - def test_test_suite_html - #TestSuite.html is the default name the Selenium Runner tries to run - _test_root_suite 'TestSuite.html' - end - - def _test_root_suite testname - get :test_file, :testname => testname - assert_response :success - - assert_tag :tag => "title", :content => "test layout" - assert_tag :tag => "script", :attributes => {:type => "text/javascript"} - assert_tag :tag => "select", :attributes => {:onchange => "openSuite(this)"}, - :descendant => {:tag => "option", :attributes => {:value => "header"}, :content => "Suites:"}, - :descendant => {:tag => "option", :attributes => {:value => "/partials"}, :content => "Partials"}, - :descendant => {:tag => "option", :attributes => {:value => "/suite_one"}, :content => "Suite one"}, - :descendant => {:tag => "option", :attributes => {:value => "/suite_two"}, :content => "Suite two"}, - :descendant => {:tag => "option", :attributes => {:value => "/suite_one/subsuite"}, :content => "Suite one.Subsuite"} - - assert_tag :tag => "table", - :descendant => {:tag => "th", :content => "All test cases"}, - :descendant => {:tag => "td", :content => "Html"}, - :descendant => {:tag => "td", :content => "Own layout"}, - :descendant => {:tag => "td", :content => "Rhtml"}, - :descendant => {:tag => "td", :content => "Rselenese"}, - :descendant => {:tag => "td", :content => "Selenese"}, - :descendant => {:tag => "td", :content => "Partials.All partials"}, - :descendant => {:tag => "td", :content => "Suite one.Suite one testcase1"}, - :descendant => {:tag => "td", :content => "Suite one.Suite one testcase2"}, - :descendant => {:tag => "td", :content => "Suite one.Subsuite.Suite one subsuite testcase"}, - :descendant => {:tag => "td", :content => "Suite two.Suite two testcase"} - end - - def test_suite_one - get :test_file, :testname => 'suite_one' - - assert_response :success - assert_tag :tag => "title", :content => "test layout" - assert_tag :tag => "script", :attributes => {:type => "text/javascript"} - assert_tag :tag => "select", :attributes => {:onchange => "openSuite(this)"}, - :descendant => {:tag => "option", :attributes => {:value => "header"}, :content => "Suites:"}, - :descendant => {:tag => "option", :attributes => {:value => ""}, :content => ".."}, - :descendant => {:tag => "option", :attributes => {:value => "/suite_one/subsuite"}, :content => "Subsuite"} - - assert_tag :tag => "table", - :descendant => {:tag => "th", :content => "Suite one"}, - :descendant => {:tag => "td", :content => "Suite one testcase1"}, - :descendant => {:tag => "td", :content => "Suite one testcase2"}, - :descendant => {:tag => "td", :content => "Subsuite.Suite one subsuite testcase"} - end - - def test_sub_suite - get :test_file, :testname => 'suite_one/subsuite' - - assert_response :success - assert_tag :tag => "title", :content => "test layout" - assert_tag :tag => "script", :attributes => {:type => "text/javascript"} - assert_tag :tag => "select", :attributes => {:onchange => "openSuite(this)"}, - :descendant => {:tag => "option", :attributes => {:value => "header"}, :content => "Suites:"}, - :descendant => {:tag => "option", :attributes => {:value => "/suite_one"}, :content => ".."} - - assert_tag :tag => "table", - :descendant => {:tag => "th", :content => "Subsuite"}, - :descendant => {:tag => "td", :content => "Suite one subsuite testcase"} - end - - def test_missing_tests_directory - def @controller.selenium_tests_path - File.join(File.dirname(__FILE__), 'invalid') - end - get :test_file, :testname => '' - assert_response 404 - assert_equal "Did not find the Selenium tests path (#{File.join(File.dirname(__FILE__), 'invalid')}). Run script/generate selenium", @response.body - end - -end diff --git a/vendor/plugins/selenium-on-rails/test/switch_environment_controller_test.rb b/vendor/plugins/selenium-on-rails/test/switch_environment_controller_test.rb deleted file mode 100644 index 66d5ac77..00000000 --- a/vendor/plugins/selenium-on-rails/test/switch_environment_controller_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' -require 'mocha' -require 'controllers/switch_environment_controller' - -class SwitchEnvironmentControllerTest < Test::Unit::TestCase - - def setup - @config = mock() - setup_controller_test(SwitchEnvironmentController) - end - - def test_index - SeleniumOnRailsConfig.expects(:get).with(:environments).returns("hello dolly") - get :index - assert @response.body.include?('hello dolly') - end -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test/test_builder_functions_authortest.rb b/vendor/plugins/selenium-on-rails/test/test_builder_functions_authortest.rb deleted file mode 100644 index be1ea33c..00000000 --- a/vendor/plugins/selenium-on-rails/test/test_builder_functions_authortest.rb +++ /dev/null @@ -1,51 +0,0 @@ -#---------------------------------------------------------------------------- -# This is a *_authortest.rb file, which means it will only run if you run: -# rake alltests -# It is not run as part of the standard test suite, as it's of limited -# value unless you're actually developing Selenium On Rails. - -#---------------------------------------------------------------------------- -# The test_builder_actions.rb and test_builder_accessors.rb files do not -# necessarily contain all the functions which are available in Selenium. -# Here we use the iedoc.xml file to find functions which might need to be -# added to the files. Ultimately it would be great not to need to do this -# process manually, however, this is a temporary step toward improving -# function parity. - -require File.dirname(__FILE__) + '/test_helper' - -class TestTheTestBuilderFunctions < Test::Unit::TestCase - - def test_functions_in_iedoc_are_supported - - base_path = File.dirname(__FILE__) + '/../' - - iedoc_file = File.read base_path + "selenium-core/iedoc.xml" - test_builder_actions_file = File.read base_path + "lib/selenium_on_rails/test_builder_actions.rb" - test_builder_accessors_file = File.read base_path + "lib/selenium_on_rails/test_builder_accessors.rb" - - # Don't include any deprecated functions - deprecated_functions = %W{dragdrop} - - iedoc_functions = iedoc_file.scan(/function *name *= *["']([a-zA-Z]+)["']/)\ - .sort.collect{|x| x[0]} - deprecated_functions - - for function_name in iedoc_functions - - function_name.gsub!(/[A-Z]/) { |s| "_" + s.downcase } - - test_description = "The function listed in the iedoc.xml file, " + - "#{function_name}, exists in the test_builder files" - - if test_builder_actions_file.match(/def *#{function_name}/) || - test_builder_accessors_file.match(/(?:def *|tt>)#{function_name}/) - assert true, test_description - else - assert false, test_description - end - end - - end - -end - diff --git a/vendor/plugins/selenium-on-rails/test/test_helper.rb b/vendor/plugins/selenium-on-rails/test/test_helper.rb deleted file mode 100644 index cac9efee..00000000 --- a/vendor/plugins/selenium-on-rails/test/test_helper.rb +++ /dev/null @@ -1,101 +0,0 @@ -ENV["RAILS_ENV"] = "test" -RAILS_ROOT = "test" unless defined?(RAILS_ROOT) -$: << File.expand_path(File.dirname(__FILE__) + "/../lib") - -require 'rubygems' -gem 'activesupport' -require 'active_support' - -gem 'actionpack' -require 'action_view/template_handler' -require 'action_view/template_handlers/builder' -require 'action_view/template_handlers/erb' -require 'action_view/template_handlers/rjs' -require 'action_view/base' -require 'action_view/partials' -require 'action_view/template_error' -require 'action_controller' - -require 'selenium_on_rails/suite_renderer' -require 'selenium_on_rails/fixture_loader' -require 'selenium_helper' -require 'controllers/selenium_controller' -require File.expand_path(File.dirname(__FILE__) + "/../routes") -require 'action_controller/test_process' - -SeleniumController.append_view_path File.expand_path(File.dirname(__FILE__)) - -def setup_controller_test(controller) - @controller = controller.new - ActionController::Routing::Routes.draw - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new -end - - -class SeleniumController - attr_accessor :layout_override - # Re-raise errors caught by the controller. - def rescue_action e - raise e - end - - def render options = nil - if override_layout? options - options[:layout] = false - super options - return response.body = @layout_override.gsub('@content_for_layout', response.body) - end - super options - end - - private - def override_layout? options - return false unless @layout_override - if options[:action] or options[:template] - options[:layout] != false #for action and template the default layout is used if not explicitly disabled - else - not [nil, false].include? options[:layout] #otherwise a layout has to be specified - end - end - -end - -class Test::Unit::TestCase - def assert_text_equal expected, actual - assert_equal clean_text(expected), clean_text(actual) - end - - def clean_text text - text.gsub("\t", ' ').gsub("\r", '').gsub("\n", '').gsub(/ * @override, :type => @override_type, :locals => local_assigns - # extract_commands_from_partial partial - # else - # render_partial_without_override partial_path, object, local_assigns, status - # end - # end - # - # def override_partial partial, type - # @override, @override_type = partial, type - # result = yield - # @override, @override_type = nil, nil - # result - # end - -end \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/_partial.rsel b/vendor/plugins/selenium-on-rails/test_data/_partial.rsel deleted file mode 100644 index d6c575a7..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/_partial.rsel +++ /dev/null @@ -1 +0,0 @@ -assert_title "Partial from #{source}" \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/backup.html~ b/vendor/plugins/selenium-on-rails/test_data/backup.html~ deleted file mode 100644 index e69de29b..00000000 diff --git a/vendor/plugins/selenium-on-rails/test_data/own_layout.html b/vendor/plugins/selenium-on-rails/test_data/own_layout.html deleted file mode 100644 index a45c5498..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/own_layout.html +++ /dev/null @@ -1,12 +0,0 @@ - - - Test case with own layout - - - - - - -
    Test own layout
    open/selenium/setup 
    - - diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/_html.html b/vendor/plugins/selenium-on-rails/test_data/partials/_html.html deleted file mode 100644 index 916ca4f7..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/_html.html +++ /dev/null @@ -1,6 +0,0 @@ -

    This should never be visible!

    - - - -
    HTML partial
    typepartialHTML partial
    -

    Neither should this!

    \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/_nesting.rsel b/vendor/plugins/selenium-on-rails/test_data/partials/_nesting.rsel deleted file mode 100644 index 28e7bf91..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/_nesting.rsel +++ /dev/null @@ -1,2 +0,0 @@ -type 'nesting', 'Nesting partial' -include_partial 'partials/rsel', :hello => hello.reverse \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/_rhtml.rhtml b/vendor/plugins/selenium-on-rails/test_data/partials/_rhtml.rhtml deleted file mode 100644 index af6599de..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/_rhtml.rhtml +++ /dev/null @@ -1,6 +0,0 @@ -

    This should never be visible!

    - - - -
    RHTML partial
    type<%= hello %>RHTML partial
    -

    Neither should this!

    \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/_rsel.rsel b/vendor/plugins/selenium-on-rails/test_data/partials/_rsel.rsel deleted file mode 100644 index 0ce0e9fe..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/_rsel.rsel +++ /dev/null @@ -1 +0,0 @@ -type hello, 'RSelenese partial' diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/_sel.sel b/vendor/plugins/selenium-on-rails/test_data/partials/_sel.sel deleted file mode 100644 index 353f0f26..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/_sel.sel +++ /dev/null @@ -1,5 +0,0 @@ -h1. This should not be visible! - -|type|partial|Selenese partial| - -p. Neither should this! \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/partials/all_partials.rsel b/vendor/plugins/selenium-on-rails/test_data/partials/all_partials.rsel deleted file mode 100644 index 08c0faf5..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/partials/all_partials.rsel +++ /dev/null @@ -1,5 +0,0 @@ -include_partial 'partial', :source => title -['html', 'rhtml', 'sel', 'rsel'].each do |format| - include_partial "partials/#{format}", :hello => 'world' -end -include_partial 'partials/nesting', :hello => 'world' \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/rhtml.rhtml b/vendor/plugins/selenium-on-rails/test_data/rhtml.rhtml deleted file mode 100644 index 2ae4e413..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/rhtml.rhtml +++ /dev/null @@ -1,7 +0,0 @@ - - -<% for page in ['/fi', '/fo', '/fum'] -%> - -<% end -%> - <%= render :partial => 'partial', :locals => {:source => 'RHTML'} %> -
    <%= @page_title %>
    open<%= page %> 
    \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/rselenese.rsel b/vendor/plugins/selenium-on-rails/test_data/rselenese.rsel deleted file mode 100644 index 425d75e6..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/rselenese.rsel +++ /dev/null @@ -1,8 +0,0 @@ -setup -setup :keep_session -test.setup :fixtures => :all -setup :fixtures => [:foo, 'bar'] -setup :clear_tables => [:foo, :bar], :fixtures => :all -assert_absolute_location :controller => 'selenium', :action => 'setup' #urls must be tested with a controller -assert_title @view.controller.controller_name #make sure we can access the view easily -include_partial 'partial', :source => 'RSelenese' \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/selenese.sel b/vendor/plugins/selenium-on-rails/test_data/selenese.sel deleted file mode 100644 index 46b1dce9..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/selenese.sel +++ /dev/null @@ -1,7 +0,0 @@ -Selenese *support* - -|open|/selenium/setup| -|goBack| -|includePartial|partial|source=Selenese| - -works. \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/suite_one/subsuite/suite_one_subsuite_testcase.sel b/vendor/plugins/selenium-on-rails/test_data/suite_one/subsuite/suite_one_subsuite_testcase.sel deleted file mode 100644 index 9c3209b6..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/suite_one/subsuite/suite_one_subsuite_testcase.sel +++ /dev/null @@ -1 +0,0 @@ -|open|/| \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase1.sel b/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase1.sel deleted file mode 100644 index 9c3209b6..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase1.sel +++ /dev/null @@ -1 +0,0 @@ -|open|/| \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase2.sel b/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase2.sel deleted file mode 100644 index 9c3209b6..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase2.sel +++ /dev/null @@ -1 +0,0 @@ -|open|/| \ No newline at end of file diff --git a/vendor/plugins/selenium-on-rails/test_data/suite_two/suite_two_testcase.sel b/vendor/plugins/selenium-on-rails/test_data/suite_two/suite_two_testcase.sel deleted file mode 100644 index 9c3209b6..00000000 --- a/vendor/plugins/selenium-on-rails/test_data/suite_two/suite_two_testcase.sel +++ /dev/null @@ -1 +0,0 @@ -|open|/| \ No newline at end of file