indirect-webrat 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +4 -0
- data/.gitignore +21 -0
- data/Gemfile +14 -0
- data/History.txt +470 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +85 -0
- data/Rakefile +143 -0
- data/Thorfile +118 -0
- data/install.rb +1 -0
- data/lib/webrat.rb +18 -0
- data/lib/webrat/adapters/mechanize.rb +94 -0
- data/lib/webrat/adapters/merb.rb +11 -0
- data/lib/webrat/adapters/rack.rb +30 -0
- data/lib/webrat/adapters/rails.rb +77 -0
- data/lib/webrat/adapters/sinatra.rb +9 -0
- data/lib/webrat/core.rb +13 -0
- data/lib/webrat/core/configuration.rb +114 -0
- data/lib/webrat/core/elements/area.rb +31 -0
- data/lib/webrat/core/elements/element.rb +33 -0
- data/lib/webrat/core/elements/field.rb +438 -0
- data/lib/webrat/core/elements/form.rb +127 -0
- data/lib/webrat/core/elements/label.rb +31 -0
- data/lib/webrat/core/elements/link.rb +93 -0
- data/lib/webrat/core/elements/select_option.rb +48 -0
- data/lib/webrat/core/locators.rb +20 -0
- data/lib/webrat/core/locators/area_locator.rb +38 -0
- data/lib/webrat/core/locators/button_locator.rb +54 -0
- data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
- data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
- data/lib/webrat/core/locators/field_locator.rb +25 -0
- data/lib/webrat/core/locators/field_named_locator.rb +41 -0
- data/lib/webrat/core/locators/form_locator.rb +19 -0
- data/lib/webrat/core/locators/label_locator.rb +34 -0
- data/lib/webrat/core/locators/link_locator.rb +82 -0
- data/lib/webrat/core/locators/locator.rb +20 -0
- data/lib/webrat/core/locators/select_option_locator.rb +59 -0
- data/lib/webrat/core/logging.rb +23 -0
- data/lib/webrat/core/matchers.rb +4 -0
- data/lib/webrat/core/matchers/have_content.rb +68 -0
- data/lib/webrat/core/matchers/have_selector.rb +85 -0
- data/lib/webrat/core/matchers/have_tag.rb +21 -0
- data/lib/webrat/core/matchers/have_xpath.rb +124 -0
- data/lib/webrat/core/methods.rb +73 -0
- data/lib/webrat/core/mime.rb +18 -0
- data/lib/webrat/core/save_and_open_page.rb +28 -0
- data/lib/webrat/core/scope.rb +362 -0
- data/lib/webrat/core/session.rb +318 -0
- data/lib/webrat/core/xml.rb +44 -0
- data/lib/webrat/core_extensions/blank.rb +58 -0
- data/lib/webrat/core_extensions/deprecate.rb +8 -0
- data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
- data/lib/webrat/core_extensions/meta_class.rb +6 -0
- data/lib/webrat/core_extensions/nil_to_query_string.rb +5 -0
- data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
- data/lib/webrat/integrations/merb.rb +10 -0
- data/lib/webrat/integrations/rack.rb +9 -0
- data/lib/webrat/integrations/rails.rb +25 -0
- data/lib/webrat/integrations/rspec-rails.rb +11 -0
- data/lib/webrat/integrations/selenium.rb +11 -0
- data/lib/webrat/merb.rb +9 -0
- data/lib/webrat/rspec-rails.rb +2 -0
- data/lib/webrat/selenium.rb +70 -0
- data/lib/webrat/selenium/application_server_factory.rb +43 -0
- data/lib/webrat/selenium/application_servers.rb +5 -0
- data/lib/webrat/selenium/application_servers/base.rb +46 -0
- data/lib/webrat/selenium/application_servers/external.rb +26 -0
- data/lib/webrat/selenium/application_servers/merb.rb +50 -0
- data/lib/webrat/selenium/application_servers/rack.rb +51 -0
- data/lib/webrat/selenium/application_servers/rails.rb +44 -0
- data/lib/webrat/selenium/application_servers/sinatra.rb +37 -0
- data/lib/webrat/selenium/location_strategy_javascript/button.js +19 -0
- data/lib/webrat/selenium/location_strategy_javascript/label.js +48 -0
- data/lib/webrat/selenium/location_strategy_javascript/webrat.js +6 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +32 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
- data/lib/webrat/selenium/matchers.rb +4 -0
- data/lib/webrat/selenium/matchers/have_content.rb +78 -0
- data/lib/webrat/selenium/matchers/have_selector.rb +57 -0
- data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
- data/lib/webrat/selenium/matchers/have_xpath.rb +53 -0
- data/lib/webrat/selenium/selenium_extensions.js +6 -0
- data/lib/webrat/selenium/selenium_rc_server.rb +89 -0
- data/lib/webrat/selenium/selenium_session.rb +276 -0
- data/lib/webrat/selenium/silence_stream.rb +18 -0
- data/spec/fakes/test_adapter.rb +33 -0
- data/spec/integration/mechanize/Rakefile +7 -0
- data/spec/integration/mechanize/config.ru +2 -0
- data/spec/integration/mechanize/sample_app.rb +35 -0
- data/spec/integration/mechanize/spec/mechanize_spec.rb +30 -0
- data/spec/integration/mechanize/spec/spec_helper.rb +29 -0
- data/spec/integration/merb/.gitignore +21 -0
- data/spec/integration/merb/Rakefile +35 -0
- data/spec/integration/merb/app/controllers/application.rb +2 -0
- data/spec/integration/merb/app/controllers/exceptions.rb +13 -0
- data/spec/integration/merb/app/controllers/testing.rb +27 -0
- data/spec/integration/merb/app/views/exceptions/not_acceptable.html.erb +63 -0
- data/spec/integration/merb/app/views/exceptions/not_found.html.erb +47 -0
- data/spec/integration/merb/app/views/layout/application.html.erb +12 -0
- data/spec/integration/merb/app/views/testing/show_form.html.erb +27 -0
- data/spec/integration/merb/app/views/testing/upload.html.erb +9 -0
- data/spec/integration/merb/config/environments/development.rb +15 -0
- data/spec/integration/merb/config/environments/rake.rb +11 -0
- data/spec/integration/merb/config/environments/test.rb +14 -0
- data/spec/integration/merb/config/init.rb +25 -0
- data/spec/integration/merb/config/rack.rb +11 -0
- data/spec/integration/merb/config/router.rb +34 -0
- data/spec/integration/merb/spec/spec.opts +1 -0
- data/spec/integration/merb/spec/spec_helper.rb +26 -0
- data/spec/integration/merb/spec/webrat_spec.rb +39 -0
- data/spec/integration/merb/tasks/merb.thor/app_script.rb +31 -0
- data/spec/integration/merb/tasks/merb.thor/common.rb +64 -0
- data/spec/integration/merb/tasks/merb.thor/gem_ext.rb +124 -0
- data/spec/integration/merb/tasks/merb.thor/main.thor +150 -0
- data/spec/integration/merb/tasks/merb.thor/ops.rb +93 -0
- data/spec/integration/merb/tasks/merb.thor/utils.rb +40 -0
- data/spec/integration/rack/Rakefile +5 -0
- data/spec/integration/rack/app.rb +89 -0
- data/spec/integration/rack/test/helper.rb +20 -0
- data/spec/integration/rack/test/webrat_rack_test.rb +74 -0
- data/spec/integration/rails/.gitignore +3 -0
- data/spec/integration/rails/Rakefile +30 -0
- data/spec/integration/rails/app/controllers/application_controller.rb +15 -0
- data/spec/integration/rails/app/controllers/buttons_controller.rb +7 -0
- data/spec/integration/rails/app/controllers/fields_controller.rb +4 -0
- data/spec/integration/rails/app/controllers/links_controller.rb +7 -0
- data/spec/integration/rails/app/controllers/webrat_controller.rb +46 -0
- data/spec/integration/rails/app/helpers/buttons_helper.rb +2 -0
- data/spec/integration/rails/app/helpers/fields_helper.rb +2 -0
- data/spec/integration/rails/app/helpers/links_helper.rb +2 -0
- data/spec/integration/rails/app/views/buttons/show.html.erb +9 -0
- data/spec/integration/rails/app/views/fields/show.html.erb +9 -0
- data/spec/integration/rails/app/views/links/show.html.erb +5 -0
- data/spec/integration/rails/app/views/webrat/before_redirect_form.html.erb +4 -0
- data/spec/integration/rails/app/views/webrat/buttons.html.erb +9 -0
- data/spec/integration/rails/app/views/webrat/form.html.erb +28 -0
- data/spec/integration/rails/app/views/webrat/within.html.erb +3 -0
- data/spec/integration/rails/config/boot.rb +109 -0
- data/spec/integration/rails/config/environment.rb +12 -0
- data/spec/integration/rails/config/environments/development.rb +17 -0
- data/spec/integration/rails/config/environments/selenium.rb +22 -0
- data/spec/integration/rails/config/environments/test.rb +22 -0
- data/spec/integration/rails/config/initializers/inflections.rb +10 -0
- data/spec/integration/rails/config/initializers/mime_types.rb +5 -0
- data/spec/integration/rails/config/initializers/new_rails_defaults.rb +17 -0
- data/spec/integration/rails/config/locales/en.yml +5 -0
- data/spec/integration/rails/config/routes.rb +19 -0
- data/spec/integration/rails/public/404.html +30 -0
- data/spec/integration/rails/public/422.html +30 -0
- data/spec/integration/rails/public/500.html +33 -0
- data/spec/integration/rails/script/about +4 -0
- data/spec/integration/rails/script/console +3 -0
- data/spec/integration/rails/script/dbconsole +3 -0
- data/spec/integration/rails/script/destroy +3 -0
- data/spec/integration/rails/script/generate +3 -0
- data/spec/integration/rails/script/performance/benchmarker +3 -0
- data/spec/integration/rails/script/performance/profiler +3 -0
- data/spec/integration/rails/script/performance/request +3 -0
- data/spec/integration/rails/script/plugin +3 -0
- data/spec/integration/rails/script/process/inspector +3 -0
- data/spec/integration/rails/script/process/reaper +3 -0
- data/spec/integration/rails/script/process/spawner +3 -0
- data/spec/integration/rails/script/runner +3 -0
- data/spec/integration/rails/script/server +3 -0
- data/spec/integration/rails/test/integration/button_click_test.rb +66 -0
- data/spec/integration/rails/test/integration/fill_in_test.rb +24 -0
- data/spec/integration/rails/test/integration/link_click_test.rb +27 -0
- data/spec/integration/rails/test/integration/webrat_test.rb +123 -0
- data/spec/integration/rails/test/test_helper.rb +27 -0
- data/spec/integration/sinatra/Rakefile +5 -0
- data/spec/integration/sinatra/classic_app.rb +63 -0
- data/spec/integration/sinatra/modular_app.rb +15 -0
- data/spec/integration/sinatra/test/classic_app_test.rb +38 -0
- data/spec/integration/sinatra/test/modular_app_test.rb +18 -0
- data/spec/integration/sinatra/test/test_helper.rb +16 -0
- data/spec/private/core/configuration_spec.rb +87 -0
- data/spec/private/core/field_spec.rb +83 -0
- data/spec/private/core/form_spec.rb +51 -0
- data/spec/private/core/link_spec.rb +24 -0
- data/spec/private/core/session_spec.rb +182 -0
- data/spec/private/mechanize/mechanize_adapter_spec.rb +96 -0
- data/spec/private/nokogiri_spec.rb +77 -0
- data/spec/private/rails/attaches_file_spec.rb +114 -0
- data/spec/private/rails/rails_adapter_spec.rb +79 -0
- data/spec/private/selenium/application_servers/rails_spec.rb +26 -0
- data/spec/public/basic_auth_spec.rb +35 -0
- data/spec/public/check_spec.rb +191 -0
- data/spec/public/choose_spec.rb +118 -0
- data/spec/public/click_area_spec.rb +106 -0
- data/spec/public/click_button_spec.rb +494 -0
- data/spec/public/click_link_spec.rb +544 -0
- data/spec/public/fill_in_spec.rb +224 -0
- data/spec/public/locators/field_by_xpath_spec.rb +19 -0
- data/spec/public/locators/field_labeled_spec.rb +172 -0
- data/spec/public/locators/field_with_id_spec.rb +16 -0
- data/spec/public/matchers/contain_spec.rb +118 -0
- data/spec/public/matchers/have_selector_spec.rb +146 -0
- data/spec/public/matchers/have_tag_spec.rb +39 -0
- data/spec/public/matchers/have_xpath_spec.rb +165 -0
- data/spec/public/reload_spec.rb +10 -0
- data/spec/public/save_and_open_spec.rb +49 -0
- data/spec/public/select_date_spec.rb +112 -0
- data/spec/public/select_datetime_spec.rb +137 -0
- data/spec/public/select_spec.rb +474 -0
- data/spec/public/select_time_spec.rb +100 -0
- data/spec/public/selenium/application_server_factory_spec.rb +49 -0
- data/spec/public/selenium/application_servers/external_spec.rb +12 -0
- data/spec/public/selenium/selenium_session_spec.rb +37 -0
- data/spec/public/set_hidden_field_spec.rb +5 -0
- data/spec/public/submit_form_spec.rb +56 -0
- data/spec/public/visit_spec.rb +58 -0
- data/spec/public/within_spec.rb +177 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +53 -0
- data/vendor/selenium-server.jar +0 -0
- data/webrat.gemspec +355 -0
- metadata +424 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require "webrat/integrations/merb"
|
|
2
|
+
|
|
3
|
+
module Webrat
|
|
4
|
+
class MerbAdapter < RackAdapter #:nodoc:
|
|
5
|
+
def initialize(context=nil)
|
|
6
|
+
app = context.respond_to?(:app) ?
|
|
7
|
+
context.app : Merb::Rack::Application.new
|
|
8
|
+
super(Rack::Test::Session.new(Rack::MockSession.new(app, "www.example.com")))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "rack/test"
|
|
2
|
+
|
|
3
|
+
module Webrat
|
|
4
|
+
class RackAdapter
|
|
5
|
+
extend Forwardable
|
|
6
|
+
|
|
7
|
+
attr :session
|
|
8
|
+
def_delegators :@session, :get, :post, :put, :delete
|
|
9
|
+
|
|
10
|
+
def initialize(session) #:nodoc:
|
|
11
|
+
@session = session
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def response_body
|
|
15
|
+
response.body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def response_code
|
|
19
|
+
response.status
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def response_headers
|
|
23
|
+
response.headers
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def response
|
|
27
|
+
@session.last_response
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require "webrat/integrations/rails"
|
|
2
|
+
require "action_controller/record_identifier"
|
|
3
|
+
|
|
4
|
+
module Webrat
|
|
5
|
+
class RailsAdapter #:nodoc:
|
|
6
|
+
include ActionController::RecordIdentifier
|
|
7
|
+
|
|
8
|
+
attr_reader :integration_session
|
|
9
|
+
|
|
10
|
+
def initialize(session)
|
|
11
|
+
@integration_session = session
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get(url, data, headers = nil)
|
|
15
|
+
do_request(:get, url, data, headers)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def post(url, data, headers = nil)
|
|
19
|
+
do_request(:post, url, data, headers)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def put(url, data, headers = nil)
|
|
23
|
+
do_request(:put, url, data, headers)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete(url, data, headers = nil)
|
|
27
|
+
do_request(:delete, url, data, headers)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def response_body
|
|
31
|
+
response.body
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def response_code
|
|
35
|
+
response.code.to_i
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def response_headers
|
|
39
|
+
response.headers
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def xml_content_type?
|
|
43
|
+
response.headers["Content-Type"].to_s =~ /xml/
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
protected
|
|
47
|
+
|
|
48
|
+
def do_request(http_method, url, data, headers) #:nodoc:
|
|
49
|
+
update_protocol(url)
|
|
50
|
+
integration_session.send(http_method, normalize_url(url), data, headers)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# remove protocol, host and anchor
|
|
54
|
+
def normalize_url(href) #:nodoc:
|
|
55
|
+
uri = URI.parse(href)
|
|
56
|
+
normalized_url = []
|
|
57
|
+
normalized_url << "#{uri.scheme}://" if uri.scheme
|
|
58
|
+
normalized_url << uri.host if uri.host
|
|
59
|
+
normalized_url << ":#{uri.port}" if uri.port && ![80,443].include?(uri.port)
|
|
60
|
+
normalized_url << uri.path if uri.path
|
|
61
|
+
normalized_url << "?#{uri.query}" if uri.query
|
|
62
|
+
normalized_url.join
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def update_protocol(href) #:nodoc:
|
|
66
|
+
if href =~ /^https:/
|
|
67
|
+
integration_session.https!(true)
|
|
68
|
+
elsif href =~ /^http:/
|
|
69
|
+
integration_session.https!(false)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def response #:nodoc:
|
|
74
|
+
integration_session.response
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
data/lib/webrat/core.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "webrat/core/configuration"
|
|
2
|
+
require "webrat/core/xml"
|
|
3
|
+
require "webrat/core/logging"
|
|
4
|
+
require "webrat/core/elements/form"
|
|
5
|
+
require "webrat/core/scope"
|
|
6
|
+
require "webrat/core/elements/link"
|
|
7
|
+
require "webrat/core/elements/area"
|
|
8
|
+
require "webrat/core/elements/label"
|
|
9
|
+
require "webrat/core/elements/select_option"
|
|
10
|
+
require "webrat/core/session"
|
|
11
|
+
require "webrat/core/methods"
|
|
12
|
+
require "webrat/core/matchers"
|
|
13
|
+
require "webrat/core/save_and_open_page"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require "webrat/core_extensions/deprecate"
|
|
2
|
+
require "pathname"
|
|
3
|
+
|
|
4
|
+
module Webrat
|
|
5
|
+
|
|
6
|
+
# Configures Webrat. If this is not done, Webrat will be created
|
|
7
|
+
# with all of the default settings.
|
|
8
|
+
def self.configure(configuration = Webrat.configuration)
|
|
9
|
+
yield configuration if block_given?
|
|
10
|
+
@@configuration = configuration
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.configuration # :nodoc:
|
|
14
|
+
@@configuration ||= Webrat::Configuration.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Webrat can be configured using the Webrat.configure method. For example:
|
|
18
|
+
#
|
|
19
|
+
# Webrat.configure do |config|
|
|
20
|
+
# config.mode = :sinatra
|
|
21
|
+
# end
|
|
22
|
+
class Configuration
|
|
23
|
+
|
|
24
|
+
# Webrat's mode, set automatically when requiring webrat/rails, webrat/merb, etc.
|
|
25
|
+
attr_reader :mode # :nodoc:
|
|
26
|
+
|
|
27
|
+
# Save and open pages with error status codes (500-599) in a browser? Defualts to true.
|
|
28
|
+
attr_writer :open_error_files
|
|
29
|
+
|
|
30
|
+
# Save and open page storage directory, defaults to "tmp" under current directory if exists, otherwise current directory
|
|
31
|
+
attr_accessor :saved_pages_dir
|
|
32
|
+
|
|
33
|
+
# Which rails environment should the selenium tests be run in? Defaults to test.
|
|
34
|
+
attr_accessor :application_environment
|
|
35
|
+
webrat_deprecate :selenium_environment, :application_environment
|
|
36
|
+
webrat_deprecate :selenium_environment=, :application_environment=
|
|
37
|
+
|
|
38
|
+
# Which port is the application running on for selenium testing? Defaults to 3001.
|
|
39
|
+
attr_accessor :application_port
|
|
40
|
+
webrat_deprecate :selenium_port, :application_port
|
|
41
|
+
webrat_deprecate :selenium_port=, :application_port=
|
|
42
|
+
|
|
43
|
+
# Which port should selenium use to access the application. Defaults to application_port
|
|
44
|
+
attr_writer :application_port_for_selenium
|
|
45
|
+
|
|
46
|
+
def application_port_for_selenium
|
|
47
|
+
@application_port_for_selenium || self.application_port
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Which underlying app framework we're testing with selenium
|
|
51
|
+
attr_accessor :application_framework
|
|
52
|
+
|
|
53
|
+
# Which server the application is running on for selenium testing? Defaults to localhost
|
|
54
|
+
attr_accessor :application_address
|
|
55
|
+
|
|
56
|
+
# Which server Selenium server is running on. Defaults to nil(server starts in webrat process and runs locally)
|
|
57
|
+
attr_accessor :selenium_server_address
|
|
58
|
+
|
|
59
|
+
# Which server Selenium port is running on. Defaults to 4444
|
|
60
|
+
attr_accessor :selenium_server_port
|
|
61
|
+
|
|
62
|
+
# Set the key that Selenium uses to determine the browser running. Default *firefox
|
|
63
|
+
attr_accessor :selenium_browser_key
|
|
64
|
+
|
|
65
|
+
# Set the timeout for waiting for the browser process to start
|
|
66
|
+
attr_accessor :selenium_browser_startup_timeout
|
|
67
|
+
|
|
68
|
+
# Set the firefox profile for selenium to use
|
|
69
|
+
attr_accessor :selenium_firefox_profile
|
|
70
|
+
|
|
71
|
+
# How many redirects to the same URL should be halted as an infinite redirect
|
|
72
|
+
# loop? Defaults to 10
|
|
73
|
+
attr_accessor :infinite_redirect_limit
|
|
74
|
+
|
|
75
|
+
# Print out the full HTML on wait failure
|
|
76
|
+
# Defaults to false
|
|
77
|
+
attr_accessor :selenium_verbose_output
|
|
78
|
+
|
|
79
|
+
def initialize # :nodoc:
|
|
80
|
+
self.open_error_files = true
|
|
81
|
+
self.application_environment = :test
|
|
82
|
+
self.application_port = 3001
|
|
83
|
+
self.application_address = 'localhost'
|
|
84
|
+
self.application_framework = :rails
|
|
85
|
+
self.selenium_server_port = 4444
|
|
86
|
+
self.infinite_redirect_limit = 10
|
|
87
|
+
self.selenium_browser_key = '*firefox'
|
|
88
|
+
self.selenium_browser_startup_timeout = 5
|
|
89
|
+
self.selenium_verbose_output = false
|
|
90
|
+
|
|
91
|
+
tmp_dir = Pathname.new(Dir.pwd).join("tmp")
|
|
92
|
+
self.saved_pages_dir = tmp_dir.exist? ? tmp_dir : Dir.pwd
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def open_error_files? #:nodoc:
|
|
96
|
+
@open_error_files ? true : false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Allows setting of webrat's mode, valid modes are:
|
|
100
|
+
# :rails, :selenium, :rack, :sinatra, :mechanize, :merb
|
|
101
|
+
def mode=(mode)
|
|
102
|
+
@mode = mode.to_sym
|
|
103
|
+
|
|
104
|
+
begin
|
|
105
|
+
require("webrat/integrations/#{mode}")
|
|
106
|
+
rescue LoadError
|
|
107
|
+
# Only some modes have integration code that needs to
|
|
108
|
+
# be loaded, so this is OK
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "webrat/core/elements/element"
|
|
2
|
+
|
|
3
|
+
module Webrat
|
|
4
|
+
class Area < Element #:nodoc:
|
|
5
|
+
|
|
6
|
+
def self.xpath_search
|
|
7
|
+
[".//area"]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def click(method = nil, options = {})
|
|
11
|
+
@session.request_page(absolute_href, :get, {})
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
def href
|
|
17
|
+
@element["href"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def absolute_href
|
|
21
|
+
if href =~ /^\?/
|
|
22
|
+
"#{@session.current_url}#{href}"
|
|
23
|
+
elsif href !~ %r{^https?://[\w|.]+(/.*)} && (href !~ /^\//)
|
|
24
|
+
"#{@session.current_url}/#{href}"
|
|
25
|
+
else
|
|
26
|
+
href
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Webrat
|
|
2
|
+
|
|
3
|
+
class Element # :nodoc:
|
|
4
|
+
|
|
5
|
+
def self.load_all(session, dom)
|
|
6
|
+
dom.xpath(*xpath_search).map do |element|
|
|
7
|
+
load(session, element)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.load(session, element)
|
|
12
|
+
return nil if element.nil?
|
|
13
|
+
session.elements[element.path] ||= self.new(session, element)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :element
|
|
17
|
+
|
|
18
|
+
def initialize(session, element)
|
|
19
|
+
@session = session
|
|
20
|
+
@element = element
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def path
|
|
24
|
+
@element.path
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"#<#{self.class} @element=#{element.inspect}>"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
require "cgi"
|
|
2
|
+
require "digest/md5"
|
|
3
|
+
require "webrat/core_extensions/blank"
|
|
4
|
+
require "webrat/core_extensions/nil_to_query_string"
|
|
5
|
+
|
|
6
|
+
require "webrat/core/elements/element"
|
|
7
|
+
|
|
8
|
+
module Webrat
|
|
9
|
+
# Raised when Webrat is asked to manipulate a disabled form field
|
|
10
|
+
class DisabledFieldError < WebratError
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Field < Element #:nodoc:
|
|
14
|
+
attr_reader :value
|
|
15
|
+
|
|
16
|
+
def self.xpath_search
|
|
17
|
+
".//button|.//input|.//textarea|.//select"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.xpath_search_excluding_hidden
|
|
21
|
+
[".//button", ".//input[ @type != 'hidden']", ".//textarea", ".//select"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.field_classes
|
|
25
|
+
@field_classes || []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.inherited(klass)
|
|
29
|
+
@field_classes ||= []
|
|
30
|
+
@field_classes << klass
|
|
31
|
+
# raise args.inspect
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.load(session, element)
|
|
35
|
+
return nil if element.nil?
|
|
36
|
+
session.elements[element.path] ||= field_class(element).new(session, element)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.field_class(element)
|
|
40
|
+
case element.name
|
|
41
|
+
when "button" then ButtonField
|
|
42
|
+
when "select"
|
|
43
|
+
if element.attributes["multiple"].nil?
|
|
44
|
+
SelectField
|
|
45
|
+
else
|
|
46
|
+
MultipleSelectField
|
|
47
|
+
end
|
|
48
|
+
when "textarea" then TextareaField
|
|
49
|
+
else
|
|
50
|
+
case element["type"]
|
|
51
|
+
when "checkbox" then CheckboxField
|
|
52
|
+
when "hidden" then HiddenField
|
|
53
|
+
when "radio" then RadioField
|
|
54
|
+
when "password" then PasswordField
|
|
55
|
+
when "file" then FileField
|
|
56
|
+
when "reset" then ResetField
|
|
57
|
+
when "submit" then ButtonField
|
|
58
|
+
when "button" then ButtonField
|
|
59
|
+
when "image" then ButtonField
|
|
60
|
+
else TextField
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def initialize(*args)
|
|
66
|
+
super
|
|
67
|
+
@value = default_value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def label_text
|
|
71
|
+
return nil if labels.empty?
|
|
72
|
+
labels.first.text
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def id
|
|
76
|
+
@element["id"]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def disabled?
|
|
80
|
+
@element.attributes.has_key?("disabled") && @element["disabled"] != 'false'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def raise_error_if_disabled
|
|
84
|
+
return unless disabled?
|
|
85
|
+
raise DisabledFieldError.new("Cannot interact with disabled form element (#{self})")
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def to_query_string
|
|
89
|
+
return nil if disabled?
|
|
90
|
+
|
|
91
|
+
query_string = case Webrat.configuration.mode
|
|
92
|
+
when :rails, :merb, :rack, :sinatra
|
|
93
|
+
build_query_string
|
|
94
|
+
when :mechanize
|
|
95
|
+
build_query_string(false)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
query_string
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def set(value)
|
|
102
|
+
@value = value
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def unset
|
|
106
|
+
@value = default_value
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
protected
|
|
110
|
+
|
|
111
|
+
def form
|
|
112
|
+
Form.load(@session, form_element)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def form_element
|
|
116
|
+
parent = @element.parent
|
|
117
|
+
|
|
118
|
+
while parent.respond_to?(:parent)
|
|
119
|
+
return parent if parent.name == 'form'
|
|
120
|
+
parent = parent.parent
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def name
|
|
125
|
+
@element["name"]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def build_query_string(escape_value=true)
|
|
129
|
+
if @value.is_a?(Array)
|
|
130
|
+
@value.collect {|value| "#{name}=#{ escape_value ? escape(value) : value }" }.join("&")
|
|
131
|
+
else
|
|
132
|
+
"#{name}=#{ escape_value ? escape(value) : value }"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def escape(value)
|
|
137
|
+
CGI.escape(value.to_s)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def escaped_value
|
|
141
|
+
CGI.escape(@value.to_s)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def labels
|
|
145
|
+
@labels ||= label_elements.map do |element|
|
|
146
|
+
Label.load(@session, element)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def label_elements
|
|
151
|
+
return @label_elements unless @label_elements.nil?
|
|
152
|
+
@label_elements = []
|
|
153
|
+
|
|
154
|
+
parent = @element.parent
|
|
155
|
+
while parent.respond_to?(:parent)
|
|
156
|
+
if parent.name == 'label'
|
|
157
|
+
@label_elements.push parent
|
|
158
|
+
break
|
|
159
|
+
end
|
|
160
|
+
parent = parent.parent
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
unless id.blank?
|
|
164
|
+
@label_elements += form.element.xpath(".//label[@for = '#{id}']")
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
@label_elements
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def default_value
|
|
171
|
+
@element["value"]
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
class ButtonField < Field #:nodoc:
|
|
176
|
+
|
|
177
|
+
def self.xpath_search
|
|
178
|
+
[".//button", ".//input[@type = 'submit']", ".//input[@type = 'button']", ".//input[@type = 'image']"]
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def to_query_string
|
|
182
|
+
return nil if @value.nil?
|
|
183
|
+
super
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def default_value
|
|
187
|
+
nil
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def click
|
|
191
|
+
raise_error_if_disabled
|
|
192
|
+
set(@element["value"]) unless @element["name"].blank?
|
|
193
|
+
form.submit
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
class HiddenField < Field #:nodoc:
|
|
199
|
+
|
|
200
|
+
def self.xpath_search
|
|
201
|
+
".//input[@type = 'hidden']"
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def to_query_string
|
|
205
|
+
if collection_name?
|
|
206
|
+
super
|
|
207
|
+
else
|
|
208
|
+
checkbox_with_same_name = form.field_named(name, CheckboxField)
|
|
209
|
+
|
|
210
|
+
if checkbox_with_same_name.to_query_string.blank?
|
|
211
|
+
super
|
|
212
|
+
else
|
|
213
|
+
nil
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
protected
|
|
219
|
+
|
|
220
|
+
def collection_name?
|
|
221
|
+
name =~ /\[\]/
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
class CheckboxField < Field #:nodoc:
|
|
227
|
+
|
|
228
|
+
def self.xpath_search
|
|
229
|
+
".//input[@type = 'checkbox']"
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def to_query_string
|
|
233
|
+
return nil if @value.nil?
|
|
234
|
+
super
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def check
|
|
238
|
+
raise_error_if_disabled
|
|
239
|
+
set(@element["value"] || "on")
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def checked?
|
|
243
|
+
@element["checked"] == "checked"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def uncheck
|
|
247
|
+
raise_error_if_disabled
|
|
248
|
+
set(nil)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
protected
|
|
252
|
+
|
|
253
|
+
def default_value
|
|
254
|
+
if @element["checked"] == "checked"
|
|
255
|
+
@element["value"] || "on"
|
|
256
|
+
else
|
|
257
|
+
nil
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
class PasswordField < Field #:nodoc:
|
|
264
|
+
|
|
265
|
+
def self.xpath_search
|
|
266
|
+
".//input[@type = 'password']"
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
class RadioField < Field #:nodoc:
|
|
272
|
+
|
|
273
|
+
def self.xpath_search
|
|
274
|
+
".//input[@type = 'radio']"
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def to_query_string
|
|
278
|
+
return nil if @value.nil?
|
|
279
|
+
super
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def choose
|
|
283
|
+
raise_error_if_disabled
|
|
284
|
+
other_options.each do |option|
|
|
285
|
+
option.set(nil)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
set(@element["value"] || "on")
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def checked?
|
|
292
|
+
@element["checked"] == "checked"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
protected
|
|
296
|
+
|
|
297
|
+
def other_options
|
|
298
|
+
form.fields.select { |f| f.name == name }
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def default_value
|
|
302
|
+
if @element["checked"] == "checked"
|
|
303
|
+
@element["value"] || "on"
|
|
304
|
+
else
|
|
305
|
+
nil
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
class TextareaField < Field #:nodoc:
|
|
312
|
+
|
|
313
|
+
def self.xpath_search
|
|
314
|
+
".//textarea"
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
protected
|
|
318
|
+
|
|
319
|
+
def default_value
|
|
320
|
+
@element.inner_html
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
class FileField < Field #:nodoc:
|
|
326
|
+
|
|
327
|
+
def self.xpath_search
|
|
328
|
+
".//input[@type = 'file']"
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
attr_accessor :content_type
|
|
332
|
+
|
|
333
|
+
def set(value, content_type = nil)
|
|
334
|
+
@original_value = @value
|
|
335
|
+
@content_type ||= content_type
|
|
336
|
+
super(value)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def digest_value
|
|
340
|
+
@value ? Digest::MD5.hexdigest(self.object_id.to_s) : ""
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def to_query_string
|
|
344
|
+
@value.nil? ? set("") : set(digest_value)
|
|
345
|
+
super
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def test_uploaded_file
|
|
349
|
+
return "" if @original_value.blank?
|
|
350
|
+
|
|
351
|
+
case Webrat.configuration.mode
|
|
352
|
+
when :rails
|
|
353
|
+
if content_type
|
|
354
|
+
ActionController::TestUploadedFile.new(@original_value, content_type)
|
|
355
|
+
else
|
|
356
|
+
ActionController::TestUploadedFile.new(@original_value)
|
|
357
|
+
end
|
|
358
|
+
when :rack, :merb
|
|
359
|
+
Rack::Test::UploadedFile.new(@original_value, content_type)
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
class TextField < Field #:nodoc:
|
|
366
|
+
def self.xpath_search
|
|
367
|
+
[".//input[@type = 'text']", ".//input[not(@type)]"]
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
class ResetField < Field #:nodoc:
|
|
372
|
+
def self.xpath_search
|
|
373
|
+
[".//input[@type = 'reset']"]
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
class SelectField < Field #:nodoc:
|
|
378
|
+
|
|
379
|
+
def self.xpath_search
|
|
380
|
+
[".//select[not(@multiple)]"]
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def options
|
|
384
|
+
@options ||= SelectOption.load_all(@session, @element)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def unset(value)
|
|
388
|
+
@value = nil
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
protected
|
|
392
|
+
|
|
393
|
+
def default_value
|
|
394
|
+
selected_options = @element.xpath(".//option[@selected = 'selected']")
|
|
395
|
+
selected_options = @element.xpath(".//option[position() = 1]") if selected_options.empty?
|
|
396
|
+
|
|
397
|
+
selected_options.map do |option|
|
|
398
|
+
return "" if option.nil?
|
|
399
|
+
option["value"] || option.inner_html
|
|
400
|
+
end.uniq.first
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
class MultipleSelectField < Field #:nodoc:
|
|
406
|
+
|
|
407
|
+
def self.xpath_search
|
|
408
|
+
[".//select[@multiple='multiple']"]
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def options
|
|
412
|
+
@options ||= SelectOption.load_all(@session, @element)
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def set(value)
|
|
416
|
+
@value << value
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def unset(value)
|
|
420
|
+
@value.delete(value)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
protected
|
|
424
|
+
|
|
425
|
+
# Overwrite SelectField definition because we don't want to select the first option
|
|
426
|
+
# (mutliples don't select the first option unlike their non multiple versions)
|
|
427
|
+
def default_value
|
|
428
|
+
selected_options = @element.xpath(".//option[@selected = 'selected']")
|
|
429
|
+
|
|
430
|
+
selected_options.map do |option|
|
|
431
|
+
return "" if option.nil?
|
|
432
|
+
option["value"] || option.inner_html
|
|
433
|
+
end.uniq
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
end
|