capybara 2.5.0 → 2.18.0
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.
- checksums.yaml +5 -5
- data/.yard/templates_custom/default/class/html/selectors.erb +38 -0
- data/.yard/templates_custom/default/class/html/setup.rb +17 -0
- data/.yard/yard_extensions.rb +78 -0
- data/.yardopts +1 -0
- data/History.md +413 -10
- data/License.txt +1 -1
- data/README.md +237 -130
- data/lib/capybara/config.rb +132 -0
- data/lib/capybara/cucumber.rb +3 -1
- data/lib/capybara/driver/base.rb +27 -6
- data/lib/capybara/driver/node.rb +14 -5
- data/lib/capybara/dsl.rb +2 -3
- data/lib/capybara/helpers.rb +13 -65
- data/lib/capybara/minitest/spec.rb +177 -0
- data/lib/capybara/minitest.rb +278 -0
- data/lib/capybara/node/actions.rb +180 -24
- data/lib/capybara/node/base.rb +17 -5
- data/lib/capybara/node/document.rb +5 -0
- data/lib/capybara/node/document_matchers.rb +15 -14
- data/lib/capybara/node/element.rb +55 -7
- data/lib/capybara/node/finders.rb +179 -67
- data/lib/capybara/node/matchers.rb +301 -105
- data/lib/capybara/node/simple.rb +15 -4
- data/lib/capybara/queries/ancestor_query.rb +25 -0
- data/lib/capybara/queries/base_query.rb +69 -3
- data/lib/capybara/queries/current_path_query.rb +17 -8
- data/lib/capybara/queries/match_query.rb +19 -0
- data/lib/capybara/queries/selector_query.rb +251 -0
- data/lib/capybara/queries/sibling_query.rb +25 -0
- data/lib/capybara/queries/text_query.rb +67 -16
- data/lib/capybara/queries/title_query.rb +4 -2
- data/lib/capybara/query.rb +3 -131
- data/lib/capybara/rack_test/browser.rb +14 -5
- data/lib/capybara/rack_test/css_handlers.rb +1 -0
- data/lib/capybara/rack_test/driver.rb +15 -8
- data/lib/capybara/rack_test/form.rb +34 -12
- data/lib/capybara/rack_test/node.rb +29 -12
- data/lib/capybara/rails.rb +3 -3
- data/lib/capybara/result.rb +104 -9
- data/lib/capybara/rspec/compound.rb +95 -0
- data/lib/capybara/rspec/features.rb +17 -6
- data/lib/capybara/rspec/matcher_proxies.rb +45 -0
- data/lib/capybara/rspec/matchers.rb +199 -80
- data/lib/capybara/rspec.rb +4 -2
- data/lib/capybara/selector/css.rb +30 -0
- data/lib/capybara/selector/filter.rb +20 -0
- data/lib/capybara/selector/filter_set.rb +74 -0
- data/lib/capybara/selector/filters/base.rb +33 -0
- data/lib/capybara/selector/filters/expression_filter.rb +40 -0
- data/lib/capybara/selector/filters/node_filter.rb +27 -0
- data/lib/capybara/selector/selector.rb +276 -0
- data/lib/capybara/selector.rb +452 -157
- data/lib/capybara/selenium/driver.rb +282 -81
- data/lib/capybara/selenium/node.rb +144 -46
- data/lib/capybara/server.rb +59 -16
- data/lib/capybara/session/config.rb +114 -0
- data/lib/capybara/session/matchers.rb +29 -19
- data/lib/capybara/session.rb +378 -143
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/public/jquery-ui.js +13 -791
- data/lib/capybara/spec/public/jquery.js +4 -9045
- data/lib/capybara/spec/public/test.js +45 -11
- data/lib/capybara/spec/session/accept_alert_spec.rb +30 -7
- data/lib/capybara/spec/session/accept_confirm_spec.rb +14 -2
- data/lib/capybara/spec/session/accept_prompt_spec.rb +35 -6
- data/lib/capybara/spec/session/all_spec.rb +45 -32
- data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +110 -0
- data/lib/capybara/spec/session/assert_current_path.rb +15 -2
- data/lib/capybara/spec/session/assert_selector.rb +29 -28
- data/lib/capybara/spec/session/assert_text.rb +59 -20
- data/lib/capybara/spec/session/assert_title.rb +25 -11
- data/lib/capybara/spec/session/attach_file_spec.rb +42 -4
- data/lib/capybara/spec/session/body_spec.rb +1 -0
- data/lib/capybara/spec/session/check_spec.rb +90 -14
- data/lib/capybara/spec/session/choose_spec.rb +31 -5
- data/lib/capybara/spec/session/click_button_spec.rb +20 -9
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +15 -9
- data/lib/capybara/spec/session/click_link_spec.rb +39 -15
- data/lib/capybara/spec/session/current_scope_spec.rb +2 -1
- data/lib/capybara/spec/session/current_url_spec.rb +12 -3
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +4 -3
- data/lib/capybara/spec/session/element/assert_match_selector.rb +36 -0
- data/lib/capybara/spec/session/element/match_css_spec.rb +23 -0
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +23 -0
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +106 -0
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +23 -1
- data/lib/capybara/spec/session/execute_script_spec.rb +22 -3
- data/lib/capybara/spec/session/fill_in_spec.rb +50 -32
- data/lib/capybara/spec/session/find_button_spec.rb +43 -2
- data/lib/capybara/spec/session/find_by_id_spec.rb +3 -2
- data/lib/capybara/spec/session/find_field_spec.rb +42 -6
- data/lib/capybara/spec/session/find_link_spec.rb +22 -3
- data/lib/capybara/spec/session/find_spec.rb +103 -57
- data/lib/capybara/spec/session/first_spec.rb +34 -18
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +103 -0
- data/lib/capybara/spec/session/{within_frame_spec.rb → frame/within_frame_spec.rb} +44 -2
- data/lib/capybara/spec/session/go_back_spec.rb +2 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_button_spec.rb +17 -8
- data/lib/capybara/spec/session/has_css_spec.rb +85 -73
- data/lib/capybara/spec/session/has_current_path_spec.rb +91 -7
- data/lib/capybara/spec/session/has_field_spec.rb +93 -58
- data/lib/capybara/spec/session/has_link_spec.rb +9 -8
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
- data/lib/capybara/spec/session/has_select_spec.rb +159 -59
- data/lib/capybara/spec/session/has_selector_spec.rb +64 -28
- data/lib/capybara/spec/session/has_table_spec.rb +1 -0
- data/lib/capybara/spec/session/has_text_spec.rb +27 -12
- data/lib/capybara/spec/session/has_title_spec.rb +22 -4
- data/lib/capybara/spec/session/has_xpath_spec.rb +32 -29
- data/lib/capybara/spec/session/headers.rb +2 -1
- data/lib/capybara/spec/session/html_spec.rb +4 -3
- data/lib/capybara/spec/session/node_spec.rb +198 -38
- data/lib/capybara/spec/session/refresh_spec.rb +28 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +46 -5
- data/lib/capybara/spec/session/response_code.rb +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -5
- data/lib/capybara/spec/session/save_page_spec.rb +34 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +31 -1
- data/lib/capybara/spec/session/screenshot_spec.rb +4 -2
- data/lib/capybara/spec/session/select_spec.rb +34 -32
- data/lib/capybara/spec/session/selectors_spec.rb +65 -0
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/text_spec.rb +4 -4
- data/lib/capybara/spec/session/title_spec.rb +2 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +42 -2
- data/lib/capybara/spec/session/unselect_spec.rb +17 -16
- data/lib/capybara/spec/session/visit_spec.rb +77 -2
- data/lib/capybara/spec/session/window/become_closed_spec.rb +12 -11
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -11
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +7 -4
- data/lib/capybara/spec/session/window/window_spec.rb +36 -29
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -7
- data/lib/capybara/spec/session/within_spec.rb +14 -6
- data/lib/capybara/spec/spec_helper.rb +37 -4
- data/lib/capybara/spec/test_app.rb +15 -3
- data/lib/capybara/spec/views/buttons.erb +1 -0
- data/lib/capybara/spec/views/fieldsets.erb +2 -1
- data/lib/capybara/spec/views/form.erb +169 -9
- data/lib/capybara/spec/views/frame_child.erb +10 -2
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +3 -2
- data/lib/capybara/spec/views/frame_two.erb +2 -1
- data/lib/capybara/spec/views/header_links.erb +1 -0
- data/lib/capybara/spec/views/host_links.erb +1 -0
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/path.erb +1 -0
- data/lib/capybara/spec/views/popup_one.erb +1 -0
- data/lib/capybara/spec/views/popup_two.erb +1 -0
- data/lib/capybara/spec/views/postback.erb +2 -1
- data/lib/capybara/spec/views/tables.erb +1 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -0
- data/lib/capybara/spec/views/with_count.erb +2 -1
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +7 -1
- data/lib/capybara/spec/views/with_html.erb +40 -2
- data/lib/capybara/spec/views/with_html_entities.erb +1 -0
- data/lib/capybara/spec/views/with_js.erb +32 -1
- data/lib/capybara/spec/views/with_scope.erb +1 -0
- data/lib/capybara/spec/views/with_simple_html.erb +2 -1
- data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
- data/lib/capybara/spec/views/with_title.erb +2 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
- data/lib/capybara/spec/views/with_windows.erb +7 -0
- data/lib/capybara/spec/views/within_frames.erb +3 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +20 -3
- data/lib/capybara.rb +189 -93
- data/spec/basic_node_spec.rb +7 -6
- data/spec/capybara_spec.rb +90 -4
- data/spec/dsl_spec.rb +3 -1
- data/spec/filter_set_spec.rb +28 -0
- data/spec/fixtures/capybara.csv +1 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +5 -1
- data/spec/minitest_spec.rb +130 -0
- data/spec/minitest_spec_spec.rb +135 -0
- data/spec/per_session_config_spec.rb +67 -0
- data/spec/rack_test_spec.rb +50 -7
- data/spec/result_spec.rb +76 -0
- data/spec/rspec/features_spec.rb +21 -8
- data/spec/rspec/scenarios_spec.rb +21 -0
- data/spec/rspec/{matchers_spec.rb → shared_spec_matchers.rb} +160 -54
- data/spec/rspec/views_spec.rb +5 -0
- data/spec/rspec_matchers_spec.rb +46 -0
- data/spec/rspec_spec.rb +79 -1
- data/spec/selector_spec.rb +199 -0
- data/spec/selenium_spec_chrome.rb +54 -9
- data/spec/selenium_spec_firefox.rb +68 -0
- data/spec/selenium_spec_marionette.rb +127 -0
- data/spec/server_spec.rb +102 -14
- data/spec/session_spec.rb +54 -0
- data/spec/shared_selenium_session.rb +215 -0
- data/spec/spec_helper.rb +7 -0
- metadata +140 -15
- data/spec/selenium_spec.rb +0 -128
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
require 'capybara/session/config'
|
|
4
|
+
|
|
5
|
+
module Capybara
|
|
6
|
+
class Config
|
|
7
|
+
extend Forwardable
|
|
8
|
+
|
|
9
|
+
OPTIONS = [:app, :reuse_server, :threadsafe, :default_wait_time, :server, :default_driver, :javascript_driver]
|
|
10
|
+
|
|
11
|
+
attr_accessor :app
|
|
12
|
+
attr_reader :reuse_server, :threadsafe
|
|
13
|
+
attr_reader :session_options
|
|
14
|
+
attr_writer :default_driver, :javascript_driver
|
|
15
|
+
|
|
16
|
+
SessionConfig::OPTIONS.each do |method|
|
|
17
|
+
def_delegators :session_options, method, "#{method}="
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
@session_options = Capybara::SessionConfig.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def reuse_server=(bool)
|
|
25
|
+
@reuse_server = bool
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def threadsafe=(bool)
|
|
29
|
+
warn "Capybara.threadsafe == true is a BETA feature and may change in future minor versions" if bool
|
|
30
|
+
raise "Threadsafe setting cannot be changed once a session is created" if (bool != threadsafe) && Session.instance_created?
|
|
31
|
+
@threadsafe = bool
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
#
|
|
36
|
+
# Return the proc that Capybara will call to run the Rack application.
|
|
37
|
+
# The block returned receives a rack app, port, and host/ip and should run a Rack handler
|
|
38
|
+
# By default, Capybara will try to run webrick.
|
|
39
|
+
#
|
|
40
|
+
def server(&block)
|
|
41
|
+
if block_given?
|
|
42
|
+
warn "DEPRECATED: Passing a block to Capybara::server is deprecated, please use Capybara::register_server instead"
|
|
43
|
+
@server = block
|
|
44
|
+
else
|
|
45
|
+
@server
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
#
|
|
51
|
+
# Set the server to use.
|
|
52
|
+
#
|
|
53
|
+
# Capybara.server = :webrick
|
|
54
|
+
# Capybara.server = :puma, { Silent: true }
|
|
55
|
+
#
|
|
56
|
+
# @overload server=(name)
|
|
57
|
+
# @param [Symbol] name Name of the server type to use
|
|
58
|
+
# @overload server=([name, options])
|
|
59
|
+
# @param [Symbol] name Name of the server type to use
|
|
60
|
+
# @param [Hash] options Options to pass to the server block
|
|
61
|
+
# @see register_server
|
|
62
|
+
#
|
|
63
|
+
def server=(name)
|
|
64
|
+
name, options = *name if name.is_a? Array
|
|
65
|
+
@server = if name.respond_to? :call
|
|
66
|
+
name
|
|
67
|
+
else
|
|
68
|
+
if options
|
|
69
|
+
Proc.new { |app, port, host| Capybara.servers[name.to_sym].call(app,port,host,options) }
|
|
70
|
+
else
|
|
71
|
+
Capybara.servers[name.to_sym]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
#
|
|
78
|
+
# @return [Symbol] The name of the driver to use by default
|
|
79
|
+
#
|
|
80
|
+
def default_driver
|
|
81
|
+
@default_driver || :rack_test
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
#
|
|
86
|
+
# @return [Symbol] The name of the driver used when JavaScript is needed
|
|
87
|
+
#
|
|
88
|
+
def javascript_driver
|
|
89
|
+
@javascript_driver || :selenium
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @deprecated Use default_max_wait_time instead
|
|
93
|
+
def default_wait_time
|
|
94
|
+
deprecate('default_wait_time', 'default_max_wait_time', true)
|
|
95
|
+
default_max_wait_time
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @deprecated Use default_max_wait_time= instead
|
|
99
|
+
def default_wait_time=(t)
|
|
100
|
+
deprecate('default_wait_time=', 'default_max_wait_time=')
|
|
101
|
+
self.default_max_wait_time = t
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def deprecate(method, alternate_method, once=false)
|
|
105
|
+
@deprecation_notified ||= {}
|
|
106
|
+
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method]
|
|
107
|
+
@deprecation_notified[method]=true
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @api private
|
|
112
|
+
class ConfigureDeprecator
|
|
113
|
+
def initialize(config)
|
|
114
|
+
@config = config
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def method_missing(m, *args, &block)
|
|
118
|
+
if @config.respond_to?(m)
|
|
119
|
+
@config.public_send(m, *args, &block)
|
|
120
|
+
elsif Capybara.respond_to?(m)
|
|
121
|
+
warn "Calling #{m} from Capybara.configure is deprecated - please call it on Capybara directly ( Capybara.#{m}(...) )"
|
|
122
|
+
Capybara.public_send(m, *args, &block)
|
|
123
|
+
else
|
|
124
|
+
super
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def respond_to_missing?(m, include_private = false)
|
|
129
|
+
@config.respond_to?(m) || Capybara.respond_to?(m) || super
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
data/lib/capybara/cucumber.rb
CHANGED
data/lib/capybara/driver/base.rb
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
class Capybara::Driver::Base
|
|
3
|
+
attr_writer :session
|
|
4
|
+
|
|
2
5
|
def current_url
|
|
3
6
|
raise NotImplementedError
|
|
4
7
|
end
|
|
@@ -7,6 +10,10 @@ class Capybara::Driver::Base
|
|
|
7
10
|
raise NotImplementedError
|
|
8
11
|
end
|
|
9
12
|
|
|
13
|
+
def refresh
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
end
|
|
16
|
+
|
|
10
17
|
def find_xpath(query)
|
|
11
18
|
raise NotImplementedError
|
|
12
19
|
end
|
|
@@ -27,14 +34,18 @@ class Capybara::Driver::Base
|
|
|
27
34
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
|
|
28
35
|
end
|
|
29
36
|
|
|
30
|
-
def execute_script(script)
|
|
37
|
+
def execute_script(script, *args)
|
|
31
38
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
|
|
32
39
|
end
|
|
33
40
|
|
|
34
|
-
def evaluate_script(script)
|
|
41
|
+
def evaluate_script(script, *args)
|
|
35
42
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script'
|
|
36
43
|
end
|
|
37
44
|
|
|
45
|
+
def evaluate_async_script(script, *args)
|
|
46
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script_asnyc'
|
|
47
|
+
end
|
|
48
|
+
|
|
38
49
|
def save_screenshot(path, options={})
|
|
39
50
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#save_screenshot'
|
|
40
51
|
end
|
|
@@ -47,8 +58,12 @@ class Capybara::Driver::Base
|
|
|
47
58
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#status_code'
|
|
48
59
|
end
|
|
49
60
|
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
##
|
|
62
|
+
#
|
|
63
|
+
# @param frame [Capybara::Node::Element, :parent, :top] The iframe element to switch to
|
|
64
|
+
#
|
|
65
|
+
def switch_to_frame(frame)
|
|
66
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_frame'
|
|
52
67
|
end
|
|
53
68
|
|
|
54
69
|
def current_window_handle
|
|
@@ -90,8 +105,8 @@ class Capybara::Driver::Base
|
|
|
90
105
|
def no_such_window_error
|
|
91
106
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
|
|
92
107
|
end
|
|
93
|
-
|
|
94
|
-
|
|
108
|
+
|
|
109
|
+
|
|
95
110
|
##
|
|
96
111
|
#
|
|
97
112
|
# Execute the block, and then accept the modal opened.
|
|
@@ -134,7 +149,13 @@ class Capybara::Driver::Base
|
|
|
134
149
|
false
|
|
135
150
|
end
|
|
136
151
|
|
|
152
|
+
def session_options
|
|
153
|
+
(@session && @session.config) || Capybara.session_options
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @deprecated This method is being removed
|
|
137
157
|
def browser_initialized?
|
|
158
|
+
warn "DEPRECATED: #browser_initialized? is deprecated and will be removed in the next version of Capybara"
|
|
138
159
|
true
|
|
139
160
|
end
|
|
140
161
|
end
|
data/lib/capybara/driver/node.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Capybara
|
|
2
3
|
module Driver
|
|
3
4
|
class Node
|
|
@@ -41,23 +42,23 @@ module Capybara
|
|
|
41
42
|
def click
|
|
42
43
|
raise NotImplementedError
|
|
43
44
|
end
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
def right_click
|
|
46
47
|
raise NotImplementedError
|
|
47
48
|
end
|
|
48
|
-
|
|
49
|
+
|
|
49
50
|
def double_click
|
|
50
51
|
raise NotImplementedError
|
|
51
52
|
end
|
|
52
|
-
|
|
53
|
+
|
|
53
54
|
def send_keys(*args)
|
|
54
55
|
raise NotImplementedError
|
|
55
56
|
end
|
|
56
|
-
|
|
57
|
+
|
|
57
58
|
def hover
|
|
58
59
|
raise NotImplementedError
|
|
59
60
|
end
|
|
60
|
-
|
|
61
|
+
|
|
61
62
|
def drag_to(element)
|
|
62
63
|
raise NotImplementedError
|
|
63
64
|
end
|
|
@@ -82,6 +83,14 @@ module Capybara
|
|
|
82
83
|
raise NotImplementedError
|
|
83
84
|
end
|
|
84
85
|
|
|
86
|
+
def readonly?
|
|
87
|
+
!!self[:readonly]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def multiple?
|
|
91
|
+
!!self[:multiple]
|
|
92
|
+
end
|
|
93
|
+
|
|
85
94
|
def path
|
|
86
95
|
raise NotSupportedByDriverError, 'Capybara::Driver::Node#path'
|
|
87
96
|
end
|
data/lib/capybara/dsl.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'capybara'
|
|
2
3
|
|
|
3
4
|
module Capybara
|
|
@@ -20,12 +21,10 @@ module Capybara
|
|
|
20
21
|
Capybara.using_session(name, &block)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
-
#
|
|
25
24
|
# Shortcut to using a different wait time.
|
|
26
25
|
#
|
|
27
26
|
def using_wait_time(seconds, &block)
|
|
28
|
-
|
|
27
|
+
page.using_wait_time(seconds, &block)
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
##
|
data/lib/capybara/helpers.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Capybara
|
|
4
5
|
|
|
@@ -27,8 +28,14 @@ module Capybara
|
|
|
27
28
|
# @param [String] text Text to escape
|
|
28
29
|
# @return [String] Escaped text
|
|
29
30
|
#
|
|
30
|
-
def to_regexp(text)
|
|
31
|
-
text.is_a?(Regexp)
|
|
31
|
+
def to_regexp(text, regexp_options=nil, exact=false)
|
|
32
|
+
if text.is_a?(Regexp)
|
|
33
|
+
text
|
|
34
|
+
else
|
|
35
|
+
escaped = Regexp.escape(normalize_whitespace(text))
|
|
36
|
+
escaped = "\\A#{escaped}\\z" if exact
|
|
37
|
+
Regexp.new(escaped, regexp_options)
|
|
38
|
+
end
|
|
32
39
|
end
|
|
33
40
|
|
|
34
41
|
##
|
|
@@ -39,76 +46,17 @@ module Capybara
|
|
|
39
46
|
# @param [String] html HTML code to inject into
|
|
40
47
|
# @return [String] The modified HTML code
|
|
41
48
|
#
|
|
42
|
-
def inject_asset_host(html)
|
|
43
|
-
if
|
|
49
|
+
def inject_asset_host(html, asset_host = Capybara.asset_host)
|
|
50
|
+
if asset_host && Nokogiri::HTML(html).css("base").empty?
|
|
44
51
|
match = html.match(/<head[^<]*?>/)
|
|
45
52
|
if match
|
|
46
|
-
return html.clone.insert match.end(0), "<base href='#{
|
|
53
|
+
return html.clone.insert match.end(0), "<base href='#{asset_host}' />"
|
|
47
54
|
end
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
html
|
|
51
58
|
end
|
|
52
59
|
|
|
53
|
-
##
|
|
54
|
-
#
|
|
55
|
-
# Checks if the given count matches the given count options.
|
|
56
|
-
# Defaults to true if no options are specified. If multiple
|
|
57
|
-
# options are provided, it tests that all conditions are met;
|
|
58
|
-
# however, if :count is supplied, all other options are ignored.
|
|
59
|
-
#
|
|
60
|
-
# @param [Integer] count The actual number. Should be coercible via Integer()
|
|
61
|
-
# @option [Range] between Count must be within the given range
|
|
62
|
-
# @option [Integer] count Count must be exactly this
|
|
63
|
-
# @option [Integer] maximum Count must be smaller than or equal to this value
|
|
64
|
-
# @option [Integer] minimum Count must be larger than or equal to this value
|
|
65
|
-
#
|
|
66
|
-
def matches_count?(count, options={})
|
|
67
|
-
return (Integer(options[:count]) == count) if options[:count]
|
|
68
|
-
return false if options[:maximum] && (Integer(options[:maximum]) < count)
|
|
69
|
-
return false if options[:minimum] && (Integer(options[:minimum]) > count)
|
|
70
|
-
return false if options[:between] && !(options[:between] === count)
|
|
71
|
-
return true
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
##
|
|
75
|
-
#
|
|
76
|
-
# Checks if a count of 0 is valid for the given options hash.
|
|
77
|
-
# Returns false if options hash does not specify any count options.
|
|
78
|
-
#
|
|
79
|
-
def expects_none?(options={})
|
|
80
|
-
if [:count, :maximum, :minimum, :between].any? { |k| options.has_key? k }
|
|
81
|
-
matches_count?(0,options)
|
|
82
|
-
else
|
|
83
|
-
false
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
##
|
|
88
|
-
#
|
|
89
|
-
# Generates a failure message given a description of the query and count
|
|
90
|
-
# options.
|
|
91
|
-
#
|
|
92
|
-
# @param [String] description Description of a query
|
|
93
|
-
# @option [Range] between Count should have been within the given range
|
|
94
|
-
# @option [Integer] count Count should have been exactly this
|
|
95
|
-
# @option [Integer] maximum Count should have been smaller than or equal to this value
|
|
96
|
-
# @option [Integer] minimum Count should have been larger than or equal to this value
|
|
97
|
-
#
|
|
98
|
-
def failure_message(description, options={})
|
|
99
|
-
message = "expected to find #{description}"
|
|
100
|
-
if options[:count]
|
|
101
|
-
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
|
|
102
|
-
elsif options[:between]
|
|
103
|
-
message << " between #{options[:between].first} and #{options[:between].last} times"
|
|
104
|
-
elsif options[:maximum]
|
|
105
|
-
message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
|
|
106
|
-
elsif options[:minimum]
|
|
107
|
-
message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
|
|
108
|
-
end
|
|
109
|
-
message
|
|
110
|
-
end
|
|
111
|
-
|
|
112
60
|
##
|
|
113
61
|
#
|
|
114
62
|
# A poor man's `pluralize`. Given two declensions, one singular and one
|
|
@@ -129,7 +77,7 @@ module Capybara
|
|
|
129
77
|
|
|
130
78
|
if defined?(Process::CLOCK_MONOTONIC)
|
|
131
79
|
def monotonic_time
|
|
132
|
-
|
|
80
|
+
Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
133
81
|
end
|
|
134
82
|
else
|
|
135
83
|
def monotonic_time
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
require 'minitest/spec'
|
|
2
|
+
|
|
3
|
+
module Capybara
|
|
4
|
+
module Minitest
|
|
5
|
+
module Expectations
|
|
6
|
+
%w(text content title current_path).each do |assertion|
|
|
7
|
+
infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
|
|
8
|
+
infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
(%w(selector xpath css link button field select table checked_field unchecked_field).flat_map do |assertion|
|
|
12
|
+
[["assert_#{assertion}", "must_have_#{assertion}"],
|
|
13
|
+
["refute_#{assertion}", "wont_have_#{assertion}"]]
|
|
14
|
+
end + [["assert_all_of_selectors", "must_have_all_of_selectors"],
|
|
15
|
+
["assert_none_of_selectors", "must_have_none_of_selectors"]] +
|
|
16
|
+
%w(selector xpath css).flat_map do |assertion|
|
|
17
|
+
[["assert_matches_#{assertion}", "must_match_#{assertion}"],
|
|
18
|
+
["refute_matches_#{assertion}", "wont_match_#{assertion}"]]
|
|
19
|
+
end).each do |(meth, new_name)|
|
|
20
|
+
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
21
|
+
def #{new_name} *args, &block
|
|
22
|
+
::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
|
|
23
|
+
end
|
|
24
|
+
EOM
|
|
25
|
+
|
|
26
|
+
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
27
|
+
def #{new_name} *args, &block
|
|
28
|
+
ctx.#{meth}(target, *args, &block)
|
|
29
|
+
end
|
|
30
|
+
EOM
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Expectation that there is xpath
|
|
35
|
+
#
|
|
36
|
+
# @!method must_have_xpath
|
|
37
|
+
# see Capybara::Node::Matchers#has_xpath?
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Expectation that there is no xpath
|
|
41
|
+
#
|
|
42
|
+
# @!method wont_have_xpath
|
|
43
|
+
# see Capybara::Node::Matchers#has_no_xpath?
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Expectation that there is css
|
|
47
|
+
#
|
|
48
|
+
# @!method must_have_css
|
|
49
|
+
# see Capybara::Node::Matchers#has_css?
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Expectation that there is no css
|
|
53
|
+
#
|
|
54
|
+
# @!method wont_have_css
|
|
55
|
+
# see Capybara::Node::Matchers#has_no_css?
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Expectation that there is link
|
|
59
|
+
#
|
|
60
|
+
# @!method must_have_link
|
|
61
|
+
# see {Capybara::Node::Matchers#has_link?}
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# Expectation that there is no link
|
|
65
|
+
#
|
|
66
|
+
# @!method wont_have_link
|
|
67
|
+
# see {Capybara::Node::Matchers#has_no_link?}
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Expectation that there is button
|
|
71
|
+
#
|
|
72
|
+
# @!method must_have_button
|
|
73
|
+
# see {Capybara::Node::Matchers#has_button?}
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# Expectation that there is no button
|
|
77
|
+
#
|
|
78
|
+
# @!method wont_have_button
|
|
79
|
+
# see {Capybara::Node::Matchers#has_no_button?}
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Expectation that there is field
|
|
83
|
+
#
|
|
84
|
+
# @!method must_have_field
|
|
85
|
+
# see {Capybara::Node::Matchers#has_field?}
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# Expectation that there is no field
|
|
89
|
+
#
|
|
90
|
+
# @!method wont_have_field
|
|
91
|
+
# see {Capybara::Node::Matchers#has_no_field?}
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# Expectation that there is checked_field
|
|
95
|
+
#
|
|
96
|
+
# @!method must_have_checked_field
|
|
97
|
+
# see {Capybara::Node::Matchers#has_checked_field?}
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# Expectation that there is no checked_field
|
|
101
|
+
#
|
|
102
|
+
# @!method wont_have_chceked_field
|
|
103
|
+
|
|
104
|
+
##
|
|
105
|
+
# Expectation that there is unchecked_field
|
|
106
|
+
#
|
|
107
|
+
# @!method must_have_unchecked_field
|
|
108
|
+
# see {Capybara::Node::Matchers#has_unchecked_field?}
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Expectation that there is no unchecked_field
|
|
112
|
+
#
|
|
113
|
+
# @!method wont_have_unchceked_field
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# Expectation that there is select
|
|
117
|
+
#
|
|
118
|
+
# @!method must_have_select
|
|
119
|
+
# see {Capybara::Node::Matchers#has_select?}
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Expectation that there is no select
|
|
123
|
+
#
|
|
124
|
+
# @!method wont_have_select
|
|
125
|
+
# see {Capybara::Node::Matchers#has_no_select?}
|
|
126
|
+
|
|
127
|
+
##
|
|
128
|
+
# Expectation that there is table
|
|
129
|
+
#
|
|
130
|
+
# @!method must_have_table
|
|
131
|
+
# see {Capybara::Node::Matchers#has_table?}
|
|
132
|
+
|
|
133
|
+
##
|
|
134
|
+
# Expectation that there is no table
|
|
135
|
+
#
|
|
136
|
+
# @!method wont_have_table
|
|
137
|
+
# see {Capybara::Node::Matchers#has_no_table?}
|
|
138
|
+
|
|
139
|
+
##
|
|
140
|
+
# Expectation that page title does match
|
|
141
|
+
#
|
|
142
|
+
# @!method must_have_title
|
|
143
|
+
# see {Capybara::Node::DocumentMatchers#assert_title}
|
|
144
|
+
|
|
145
|
+
##
|
|
146
|
+
# Expectation that page title does not match
|
|
147
|
+
#
|
|
148
|
+
# @!method wont_have_title
|
|
149
|
+
# see {Capybara::Node::DocumentMatchers#assert_no_title}
|
|
150
|
+
|
|
151
|
+
##
|
|
152
|
+
# Expectation that current path matches
|
|
153
|
+
#
|
|
154
|
+
# @!method must_have_current_path
|
|
155
|
+
# see {Capybara::SessionMatchers#assert_current_path}
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# Expectation that current page does not match
|
|
159
|
+
#
|
|
160
|
+
# @!method wont_have_current_path
|
|
161
|
+
# see {Capybara::SessionMatchers#assert_no_current_path}
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
class Capybara::Session
|
|
168
|
+
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
class Capybara::Node::Base
|
|
172
|
+
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
class Capybara::Node::Simple
|
|
176
|
+
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
|
177
|
+
end
|