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
data/lib/capybara.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'timeout'
|
|
2
3
|
require 'nokogiri'
|
|
3
4
|
require 'xpath'
|
|
5
|
+
require 'forwardable'
|
|
6
|
+
require 'capybara/config'
|
|
4
7
|
|
|
5
8
|
module Capybara
|
|
6
9
|
class CapybaraError < StandardError; end
|
|
@@ -18,13 +21,41 @@ module Capybara
|
|
|
18
21
|
class WindowError < CapybaraError; end
|
|
19
22
|
class ReadOnlyElementError < CapybaraError; end
|
|
20
23
|
|
|
24
|
+
|
|
21
25
|
class << self
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
extend Forwardable
|
|
27
|
+
|
|
28
|
+
# DelegateCapybara global configurations
|
|
29
|
+
# @!method app
|
|
30
|
+
# See {Capybara.configure}
|
|
31
|
+
# @!method reuse_server
|
|
32
|
+
# See {Capybara.configure}
|
|
33
|
+
# @!method threadsafe
|
|
34
|
+
# See {Capybara.configure}
|
|
35
|
+
# @!method server
|
|
36
|
+
# See {Capybara.configure}
|
|
37
|
+
# @!method default_driver
|
|
38
|
+
# See {Capybara.configure}
|
|
39
|
+
# @!method javascript_driver
|
|
40
|
+
# See {Capybara.configure}
|
|
41
|
+
Config::OPTIONS.each do |method|
|
|
42
|
+
def_delegators :config, method, "#{method}="
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Delegate Capybara global configurations
|
|
46
|
+
# @!method default_selector
|
|
47
|
+
# See {Capybara.configure}
|
|
48
|
+
# @!method default_max_wait_time
|
|
49
|
+
# See {Capybara.configure}
|
|
50
|
+
# @!method app_host
|
|
51
|
+
# See {Capybara.configure}
|
|
52
|
+
# @!method always_include_port
|
|
53
|
+
# See {Capybara.configure}
|
|
54
|
+
# @!method wait_on_first_by_default
|
|
55
|
+
# See {Capybara.configure}
|
|
56
|
+
SessionConfig::OPTIONS.each do |method|
|
|
57
|
+
def_delegators :config, method, "#{method}="
|
|
58
|
+
end
|
|
28
59
|
|
|
29
60
|
##
|
|
30
61
|
#
|
|
@@ -37,27 +68,33 @@ module Capybara
|
|
|
37
68
|
#
|
|
38
69
|
# === Configurable options
|
|
39
70
|
#
|
|
40
|
-
# [app_host = String]
|
|
41
|
-
# [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL (Default: false)
|
|
42
|
-
# [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
|
|
43
|
-
# [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
|
|
44
|
-
# [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
|
|
45
|
-
# [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [StandardError])
|
|
46
|
-
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
|
|
47
|
-
# [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
|
|
48
|
-
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
|
|
49
|
-
# [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
|
|
50
|
-
# [
|
|
51
|
-
# [wait_on_first_by_default = Boolean] Whether Node#first defaults to Capybara waiting behavior for at least 1 element to match (Default: false)
|
|
71
|
+
# [app_host = String/nil] The default host to use when giving a relative URL to visit, must be a valid URL e.g. http://www.example.com
|
|
72
|
+
# [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL unless another port is explicitly specified (Default: false)
|
|
73
|
+
# [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
|
|
74
|
+
# [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
|
|
75
|
+
# [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
|
|
76
|
+
# [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [StandardError])
|
|
77
|
+
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
|
|
78
|
+
# [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
|
|
79
|
+
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
|
|
80
|
+
# [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
|
|
81
|
+
# [save_path = String] Where to put pages saved through save_(page|screenshot), save_and_open_(page|screenshot) (Default: Dir.pwd)
|
|
82
|
+
# [wait_on_first_by_default = Boolean] Whether Node#first defaults to Capybara waiting behavior for at least 1 element to match (Default: false)
|
|
83
|
+
# [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
|
|
84
|
+
# [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
|
|
85
|
+
# [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
|
|
86
|
+
# [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
|
|
87
|
+
# [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
|
|
88
|
+
#
|
|
52
89
|
# === DSL Options
|
|
53
90
|
#
|
|
54
91
|
# when using capybara/dsl, the following options are also available:
|
|
55
92
|
#
|
|
56
|
-
# [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
|
|
57
|
-
# [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
|
|
93
|
+
# [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
|
|
94
|
+
# [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
|
|
58
95
|
#
|
|
59
96
|
def configure
|
|
60
|
-
yield
|
|
97
|
+
yield ConfigureDeprecator.new(config)
|
|
61
98
|
end
|
|
62
99
|
|
|
63
100
|
##
|
|
@@ -77,6 +114,26 @@ module Capybara
|
|
|
77
114
|
drivers[name] = block
|
|
78
115
|
end
|
|
79
116
|
|
|
117
|
+
##
|
|
118
|
+
#
|
|
119
|
+
# Register a new server for Capybara.
|
|
120
|
+
#
|
|
121
|
+
# Capybara.register_server :webrick do |app, port, host|
|
|
122
|
+
# require 'rack/handler/webrick'
|
|
123
|
+
# Rack::Handler::WEBrick.run(app, ...)
|
|
124
|
+
# end
|
|
125
|
+
#
|
|
126
|
+
# @param [Symbol] name The name of the new driver
|
|
127
|
+
# @yield [app, port, host] This block takes a rack app and a port and returns a rack server listening on that port
|
|
128
|
+
# @yieldparam [<Rack>] app The rack application that this server will contain.
|
|
129
|
+
# @yieldparam port The port number the server should listen on
|
|
130
|
+
# @yieldparam host The host/ip to bind to
|
|
131
|
+
# @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
|
|
132
|
+
#
|
|
133
|
+
def register_server(name, &block)
|
|
134
|
+
servers[name.to_sym] = block
|
|
135
|
+
end
|
|
136
|
+
|
|
80
137
|
##
|
|
81
138
|
#
|
|
82
139
|
# Add a new selector to Capybara. Selectors can be used by various methods in Capybara
|
|
@@ -109,29 +166,30 @@ module Capybara
|
|
|
109
166
|
Capybara::Selector.add(name, &block)
|
|
110
167
|
end
|
|
111
168
|
|
|
112
|
-
def drivers
|
|
113
|
-
@drivers ||= {}
|
|
114
|
-
end
|
|
115
|
-
|
|
116
169
|
##
|
|
117
170
|
#
|
|
118
|
-
#
|
|
171
|
+
# Modify a selector previously created by {Capybara.add_selector}.
|
|
172
|
+
# For example, adding a new filter to the :button selector to filter based on
|
|
173
|
+
# button style (a class) might look like this
|
|
119
174
|
#
|
|
120
|
-
# Capybara.
|
|
121
|
-
#
|
|
122
|
-
# Rack::Handler::Mongrel.run(app, :Port => port)
|
|
175
|
+
# Capybara.modify_selector(:button) do
|
|
176
|
+
# filter (:style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
|
|
123
177
|
# end
|
|
124
178
|
#
|
|
125
|
-
# By default, Capybara will try to run webrick.
|
|
126
179
|
#
|
|
127
|
-
# @
|
|
180
|
+
# @param [Symbol] name The name of the selector to modify
|
|
181
|
+
# @yield A block executed in the context of the existing {Capybara::Selector}
|
|
128
182
|
#
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
183
|
+
def modify_selector(name, &block)
|
|
184
|
+
Capybara::Selector.update(name, &block)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def drivers
|
|
188
|
+
@drivers ||= {}
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def servers
|
|
192
|
+
@servers ||= {}
|
|
135
193
|
end
|
|
136
194
|
|
|
137
195
|
##
|
|
@@ -140,7 +198,16 @@ module Capybara
|
|
|
140
198
|
# in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers},
|
|
141
199
|
# {Capybara::Node::Finders} and {Capybara::Node::DocumentMatchers}. This allows you to query
|
|
142
200
|
# any string containing HTML in the exact same way you would query the current document in a Capybara
|
|
143
|
-
# session.
|
|
201
|
+
# session.
|
|
202
|
+
#
|
|
203
|
+
# Example: A single element
|
|
204
|
+
#
|
|
205
|
+
# node = Capybara.string('<a href="foo">bar</a>')
|
|
206
|
+
# anchor = node.first('a')
|
|
207
|
+
# anchor[:href] #=> 'foo'
|
|
208
|
+
# anchor.text #=> 'bar'
|
|
209
|
+
#
|
|
210
|
+
# Example: Multiple elements
|
|
144
211
|
#
|
|
145
212
|
# node = Capybara.string <<-HTML
|
|
146
213
|
# <ul>
|
|
@@ -150,7 +217,7 @@ module Capybara
|
|
|
150
217
|
# HTML
|
|
151
218
|
#
|
|
152
219
|
# node.find('#projects').text # => 'Projects'
|
|
153
|
-
# node.has_selector?('li#home', :
|
|
220
|
+
# node.has_selector?('li#home', text: 'Home')
|
|
154
221
|
# node.has_selector?('#projects')
|
|
155
222
|
# node.find('ul').find('li:first-child').text # => 'Home'
|
|
156
223
|
#
|
|
@@ -168,19 +235,10 @@ module Capybara
|
|
|
168
235
|
# manually.
|
|
169
236
|
#
|
|
170
237
|
# @param [Rack Application] app The rack application to run
|
|
171
|
-
# @param [
|
|
238
|
+
# @param [Integer] port The port to run the application on
|
|
172
239
|
#
|
|
173
240
|
def run_default_server(app, port)
|
|
174
|
-
|
|
175
|
-
Rack::Handler::WEBrick.run(app, :Host => server_host, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
##
|
|
179
|
-
#
|
|
180
|
-
# @return [Symbol] The name of the driver to use by default
|
|
181
|
-
#
|
|
182
|
-
def default_driver
|
|
183
|
-
@default_driver || :rack_test
|
|
241
|
+
servers[:webrick].call(app, port, server_host)
|
|
184
242
|
end
|
|
185
243
|
|
|
186
244
|
##
|
|
@@ -188,16 +246,20 @@ module Capybara
|
|
|
188
246
|
# @return [Symbol] The name of the driver currently in use
|
|
189
247
|
#
|
|
190
248
|
def current_driver
|
|
191
|
-
|
|
249
|
+
if threadsafe
|
|
250
|
+
Thread.current['capybara_current_driver']
|
|
251
|
+
else
|
|
252
|
+
@current_driver
|
|
253
|
+
end || default_driver
|
|
192
254
|
end
|
|
193
255
|
alias_method :mode, :current_driver
|
|
194
256
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
257
|
+
def current_driver=(name)
|
|
258
|
+
if threadsafe
|
|
259
|
+
Thread.current['capybara_current_driver'] = name
|
|
260
|
+
else
|
|
261
|
+
@current_driver = name
|
|
262
|
+
end
|
|
201
263
|
end
|
|
202
264
|
|
|
203
265
|
##
|
|
@@ -205,7 +267,7 @@ module Capybara
|
|
|
205
267
|
# Use the default driver as the current driver
|
|
206
268
|
#
|
|
207
269
|
def use_default_driver
|
|
208
|
-
|
|
270
|
+
self.current_driver = nil
|
|
209
271
|
end
|
|
210
272
|
|
|
211
273
|
##
|
|
@@ -217,15 +279,7 @@ module Capybara
|
|
|
217
279
|
Capybara.current_driver = driver
|
|
218
280
|
yield
|
|
219
281
|
ensure
|
|
220
|
-
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
##
|
|
224
|
-
#
|
|
225
|
-
# @return [String] The IP address bound by default server
|
|
226
|
-
#
|
|
227
|
-
def server_host
|
|
228
|
-
@server_host || '127.0.0.1'
|
|
282
|
+
self.current_driver = previous_driver
|
|
229
283
|
end
|
|
230
284
|
|
|
231
285
|
##
|
|
@@ -256,7 +310,8 @@ module Capybara
|
|
|
256
310
|
# as cookies.
|
|
257
311
|
#
|
|
258
312
|
def reset_sessions!
|
|
259
|
-
|
|
313
|
+
#reset in reverse so sessions that started servers are reset last
|
|
314
|
+
session_pool.reverse_each { |_mode, session| session.reset! }
|
|
260
315
|
end
|
|
261
316
|
alias_method :reset!, :reset_sessions!
|
|
262
317
|
|
|
@@ -267,7 +322,19 @@ module Capybara
|
|
|
267
322
|
# @return [Symbol] The name of the currently used session.
|
|
268
323
|
#
|
|
269
324
|
def session_name
|
|
270
|
-
|
|
325
|
+
if threadsafe
|
|
326
|
+
Thread.current['capybara_session_name'] ||= :default
|
|
327
|
+
else
|
|
328
|
+
@session_name ||= :default
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def session_name=(name)
|
|
333
|
+
if threadsafe
|
|
334
|
+
Thread.current['capybara_session_name'] = name
|
|
335
|
+
else
|
|
336
|
+
@session_name = name
|
|
337
|
+
end
|
|
271
338
|
end
|
|
272
339
|
|
|
273
340
|
##
|
|
@@ -275,11 +342,19 @@ module Capybara
|
|
|
275
342
|
# Yield a block using a specific session name.
|
|
276
343
|
#
|
|
277
344
|
def using_session(name)
|
|
278
|
-
|
|
345
|
+
previous_session_info = {
|
|
346
|
+
session_name: session_name,
|
|
347
|
+
current_driver: current_driver,
|
|
348
|
+
app: app
|
|
349
|
+
}
|
|
279
350
|
self.session_name = name
|
|
280
351
|
yield
|
|
281
352
|
ensure
|
|
282
|
-
self.session_name =
|
|
353
|
+
self.session_name = previous_session_info[:session_name]
|
|
354
|
+
if threadsafe
|
|
355
|
+
self.current_driver = previous_session_info[:current_driver]
|
|
356
|
+
self.app = previous_session_info[:app]
|
|
357
|
+
end
|
|
283
358
|
end
|
|
284
359
|
|
|
285
360
|
##
|
|
@@ -292,21 +367,13 @@ module Capybara
|
|
|
292
367
|
def HTML(html)
|
|
293
368
|
Nokogiri::HTML(html).tap do |document|
|
|
294
369
|
document.xpath('//textarea').each do |textarea|
|
|
295
|
-
textarea
|
|
370
|
+
textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/,'')
|
|
296
371
|
end
|
|
297
372
|
end
|
|
298
373
|
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
deprecate('default_wait_time', 'default_max_wait_time', true)
|
|
303
|
-
default_max_wait_time
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
# @deprecated Use default_max_wait_time= instead
|
|
307
|
-
def default_wait_time=(t)
|
|
308
|
-
deprecate('default_wait_time=', 'default_max_wait_time=')
|
|
309
|
-
self.default_max_wait_time = t
|
|
374
|
+
|
|
375
|
+
def session_options
|
|
376
|
+
config.session_options
|
|
310
377
|
end
|
|
311
378
|
|
|
312
379
|
def included(base)
|
|
@@ -314,13 +381,10 @@ module Capybara
|
|
|
314
381
|
warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead."
|
|
315
382
|
end
|
|
316
383
|
|
|
317
|
-
def deprecate(method, alternate_method, once=false)
|
|
318
|
-
@deprecation_notified ||= {}
|
|
319
|
-
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method]
|
|
320
|
-
@deprecation_notified[method]=true
|
|
321
|
-
end
|
|
322
|
-
|
|
323
384
|
private
|
|
385
|
+
def config
|
|
386
|
+
@config ||= Capybara::Config.new
|
|
387
|
+
end
|
|
324
388
|
|
|
325
389
|
def session_pool
|
|
326
390
|
@session_pool ||= {}
|
|
@@ -337,7 +401,6 @@ module Capybara
|
|
|
337
401
|
|
|
338
402
|
require 'capybara/helpers'
|
|
339
403
|
require 'capybara/session'
|
|
340
|
-
require 'capybara/dsl'
|
|
341
404
|
require 'capybara/window'
|
|
342
405
|
require 'capybara/server'
|
|
343
406
|
require 'capybara/selector'
|
|
@@ -345,11 +408,15 @@ module Capybara
|
|
|
345
408
|
require 'capybara/version'
|
|
346
409
|
|
|
347
410
|
require 'capybara/queries/base_query'
|
|
348
|
-
require 'capybara/
|
|
411
|
+
require 'capybara/queries/selector_query'
|
|
349
412
|
require 'capybara/queries/text_query'
|
|
350
413
|
require 'capybara/queries/title_query'
|
|
351
414
|
require 'capybara/queries/current_path_query'
|
|
352
|
-
|
|
415
|
+
require 'capybara/queries/match_query'
|
|
416
|
+
require 'capybara/queries/ancestor_query'
|
|
417
|
+
require 'capybara/queries/sibling_query'
|
|
418
|
+
require 'capybara/query'
|
|
419
|
+
|
|
353
420
|
require 'capybara/node/finders'
|
|
354
421
|
require 'capybara/node/matchers'
|
|
355
422
|
require 'capybara/node/actions'
|
|
@@ -372,10 +439,24 @@ module Capybara
|
|
|
372
439
|
require 'capybara/selenium/driver'
|
|
373
440
|
end
|
|
374
441
|
|
|
442
|
+
Capybara.register_server :default do |app, port, _host|
|
|
443
|
+
Capybara.run_default_server(app, port)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
Capybara.register_server :webrick do |app, port, host, options={}|
|
|
447
|
+
require 'rack/handler/webrick'
|
|
448
|
+
Rack::Handler::WEBrick.run(app, {Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0)}.merge(options))
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
Capybara.register_server :puma do |app, port, host, options={}|
|
|
452
|
+
require 'rack/handler/puma'
|
|
453
|
+
Rack::Handler::Puma.run(app, {Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false}.merge(options))
|
|
454
|
+
end
|
|
455
|
+
|
|
375
456
|
Capybara.configure do |config|
|
|
376
457
|
config.always_include_port = false
|
|
377
458
|
config.run_server = true
|
|
378
|
-
config.server
|
|
459
|
+
config.server = :default
|
|
379
460
|
config.default_selector = :css
|
|
380
461
|
config.default_max_wait_time = 2
|
|
381
462
|
config.ignore_hidden_elements = true
|
|
@@ -383,10 +464,14 @@ Capybara.configure do |config|
|
|
|
383
464
|
config.automatic_reload = true
|
|
384
465
|
config.match = :smart
|
|
385
466
|
config.exact = false
|
|
467
|
+
config.exact_text = false
|
|
386
468
|
config.raise_server_errors = true
|
|
387
469
|
config.server_errors = [StandardError]
|
|
388
470
|
config.visible_text_only = false
|
|
389
471
|
config.wait_on_first_by_default = false
|
|
472
|
+
config.automatic_label_click = false
|
|
473
|
+
config.enable_aria_label = false
|
|
474
|
+
config.reuse_server = true
|
|
390
475
|
end
|
|
391
476
|
|
|
392
477
|
Capybara.register_driver :rack_test do |app|
|
|
@@ -396,3 +481,14 @@ end
|
|
|
396
481
|
Capybara.register_driver :selenium do |app|
|
|
397
482
|
Capybara::Selenium::Driver.new(app)
|
|
398
483
|
end
|
|
484
|
+
|
|
485
|
+
Capybara.register_driver :selenium_chrome do |app|
|
|
486
|
+
Capybara::Selenium::Driver.new(app, :browser => :chrome)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
Capybara.register_driver :selenium_chrome_headless do |app|
|
|
490
|
+
browser_options = ::Selenium::WebDriver::Chrome::Options.new()
|
|
491
|
+
browser_options.args << '--headless'
|
|
492
|
+
browser_options.args << '--disable-gpu'
|
|
493
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
|
494
|
+
end
|
data/spec/basic_node_spec.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
|
|
3
4
|
RSpec.describe Capybara do
|
|
@@ -51,7 +52,7 @@ RSpec.describe Capybara do
|
|
|
51
52
|
|
|
52
53
|
it "allows using custom matchers" do
|
|
53
54
|
Capybara.add_selector :lifeform do
|
|
54
|
-
xpath { |name| "
|
|
55
|
+
xpath { |name| ".//option[contains(.,'#{name}')]" }
|
|
55
56
|
end
|
|
56
57
|
expect(string).to have_selector(:id, "page")
|
|
57
58
|
expect(string).not_to have_selector(:id, 'does-not-exist')
|
|
@@ -68,13 +69,13 @@ RSpec.describe Capybara do
|
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
it "allows using matchers with text option" do
|
|
71
|
-
expect(string).to have_css('h1', :
|
|
72
|
-
expect(string).not_to have_css('h1', :
|
|
72
|
+
expect(string).to have_css('h1', text: 'Totally awesome')
|
|
73
|
+
expect(string).not_to have_css('h1', text: 'Not so awesome')
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
it "allows finding only visible nodes" do
|
|
76
|
-
expect(string.all(:css, '#secret', :
|
|
77
|
-
expect(string.all(:css, '#secret', :
|
|
77
|
+
expect(string.all(:css, '#secret', visible: true)).to be_empty
|
|
78
|
+
expect(string.all(:css, '#secret', visible: false).size).to eq(1)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
it "allows finding elements and extracting text from them" do
|
|
@@ -100,7 +101,7 @@ RSpec.describe Capybara do
|
|
|
100
101
|
|
|
101
102
|
it "allows finding elements and checking if they are visible" do
|
|
102
103
|
expect(string.find('//h1')).to be_visible
|
|
103
|
-
expect(string.find(:css, "#secret", :
|
|
104
|
+
expect(string.find(:css, "#secret", visible: false)).not_to be_visible
|
|
104
105
|
end
|
|
105
106
|
|
|
106
107
|
it "allows finding elements and checking if they are disabled" do
|
data/spec/capybara_spec.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
|
|
3
4
|
RSpec.describe Capybara do
|
|
@@ -13,8 +14,8 @@ RSpec.describe Capybara do
|
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
it "should be accesible as the deprecated default_wait_time" do
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time= is deprecated, please use #default_max_wait_time= instead')
|
|
18
|
+
expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time is deprecated, please use #default_max_wait_time instead')
|
|
18
19
|
@previous_default_time = Capybara.default_max_wait_time
|
|
19
20
|
Capybara.default_wait_time = 5
|
|
20
21
|
expect(Capybara.default_wait_time).to eq(5)
|
|
@@ -33,9 +34,24 @@ RSpec.describe Capybara do
|
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
describe '.register_server' do
|
|
38
|
+
it "should add a new server" do
|
|
39
|
+
handler = double("handler")
|
|
40
|
+
Capybara.register_server :blob do |app, port, host|
|
|
41
|
+
handler.run
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
expect(Capybara.servers).to have_key(:blob)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
36
48
|
describe ".server" do
|
|
49
|
+
before do
|
|
50
|
+
@old_server = Capybara.server
|
|
51
|
+
end
|
|
52
|
+
|
|
37
53
|
after do
|
|
38
|
-
Capybara.server
|
|
54
|
+
Capybara.server(&@old_server)
|
|
39
55
|
end
|
|
40
56
|
|
|
41
57
|
it "should default to a proc that calls run_default_server" do
|
|
@@ -49,11 +65,81 @@ RSpec.describe Capybara do
|
|
|
49
65
|
Capybara.server(&server)
|
|
50
66
|
expect(Capybara.server).to eq(server)
|
|
51
67
|
end
|
|
68
|
+
|
|
69
|
+
it "should have :webrick registered" do
|
|
70
|
+
require 'rack/handler/webrick'
|
|
71
|
+
mock_app = double('app')
|
|
72
|
+
Capybara.server = :webrick
|
|
73
|
+
expect(Rack::Handler::WEBrick).to receive(:run)
|
|
74
|
+
Capybara.server.call(mock_app, 8000)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should have :puma registered" do
|
|
78
|
+
require 'rack/handler/puma'
|
|
79
|
+
mock_app = double('app')
|
|
80
|
+
Capybara.server = :puma
|
|
81
|
+
expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 8000))
|
|
82
|
+
Capybara.server.call(mock_app, 8000)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should pass options to server" do
|
|
86
|
+
require 'rack/handler/puma'
|
|
87
|
+
mock_app = double('app')
|
|
88
|
+
Capybara.server = :puma, { Silent: true }
|
|
89
|
+
expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 9000, Silent: true))
|
|
90
|
+
Capybara.server.call(mock_app, 9000)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe 'app_host' do
|
|
95
|
+
after do
|
|
96
|
+
Capybara.app_host = nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should warn if not a valid URL" do
|
|
100
|
+
expect { Capybara.app_host = "www.example.com" }.to raise_error(ArgumentError, /Capybara\.app_host should be set to a url/)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should not warn if a valid URL" do
|
|
104
|
+
expect { Capybara.app_host = "http://www.example.com" }.not_to raise_error
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should not warn if nil" do
|
|
108
|
+
expect { Capybara.app_host = nil }.not_to raise_error
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe 'default_host' do
|
|
113
|
+
around do |test|
|
|
114
|
+
old_default = Capybara.default_host
|
|
115
|
+
test.run
|
|
116
|
+
Capybara.default_host = old_default
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should warn if not a valid URL" do
|
|
120
|
+
expect { Capybara.default_host = "www.example.com" }.to raise_error(ArgumentError, /Capybara\.default_host should be set to a url/)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should not warn if a valid URL" do
|
|
124
|
+
expect { Capybara.default_host = "http://www.example.com" }.not_to raise_error
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe "configure" do
|
|
129
|
+
it 'deprecates calling non configuration option methods in configure' do
|
|
130
|
+
expect_any_instance_of(Kernel).to receive(:warn).
|
|
131
|
+
with('Calling register_driver from Capybara.configure is deprecated - please call it on Capybara directly ( Capybara.register_driver(...) )')
|
|
132
|
+
Capybara.configure do |config|
|
|
133
|
+
config.register_driver(:random_name) do
|
|
134
|
+
#just a random block
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
52
138
|
end
|
|
53
139
|
end
|
|
54
140
|
|
|
55
141
|
RSpec.describe Capybara::Session do
|
|
56
|
-
context 'with
|
|
142
|
+
context 'with nonexistent driver' do
|
|
57
143
|
it "should raise an error" do
|
|
58
144
|
expect {
|
|
59
145
|
Capybara::Session.new(:quox, TestApp).driver
|
data/spec/dsl_spec.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'spec_helper'
|
|
2
3
|
require 'capybara/dsl'
|
|
3
4
|
|
|
@@ -5,7 +6,7 @@ class TestClass
|
|
|
5
6
|
include Capybara::DSL
|
|
6
7
|
end
|
|
7
8
|
|
|
8
|
-
Capybara::SpecHelper.run_specs TestClass.new, "DSL", :
|
|
9
|
+
Capybara::SpecHelper.run_specs TestClass.new, "DSL", capybara_skip: [
|
|
9
10
|
:js,
|
|
10
11
|
:modals,
|
|
11
12
|
:screenshot,
|
|
@@ -15,6 +16,7 @@ Capybara::SpecHelper.run_specs TestClass.new, "DSL", :capybara_skip => [
|
|
|
15
16
|
:server,
|
|
16
17
|
:hover,
|
|
17
18
|
:about_scheme,
|
|
19
|
+
:psc
|
|
18
20
|
]
|
|
19
21
|
|
|
20
22
|
RSpec.describe Capybara::DSL do
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
RSpec.describe Capybara::Selector::FilterSet do
|
|
5
|
+
after do
|
|
6
|
+
Capybara::Selector::FilterSet.remove(:test)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "allows node filters" do
|
|
10
|
+
fs = Capybara::Selector::FilterSet.add(:test) do
|
|
11
|
+
filter(:node_test, :boolean) { |node, value| true }
|
|
12
|
+
expression_filter(:expression_test, :boolean) { |expr, value| true }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
expect(fs.node_filters.keys).to include(:node_test)
|
|
16
|
+
expect(fs.node_filters.keys).not_to include(:expression_test)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "allows expression filters" do
|
|
20
|
+
fs = Capybara::Selector::FilterSet.add(:test) do
|
|
21
|
+
filter(:node_test, :boolean) { |node, value| true }
|
|
22
|
+
expression_filter(:expression_test, :boolean) { |expr, value| true }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
expect(fs.expression_filters.keys).to include(:expression_test)
|
|
26
|
+
expect(fs.expression_filters.keys).not_to include(:node_test)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test, mime-type, file
|