capybara 2.18.0 → 3.40.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 +4 -4
- data/.yardopts +1 -1
- data/History.md +945 -12
- data/License.txt +1 -1
- data/README.md +264 -90
- data/lib/capybara/config.rb +29 -57
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +35 -18
- data/lib/capybara/driver/node.rb +40 -10
- data/lib/capybara/dsl.rb +10 -7
- data/lib/capybara/helpers.rb +70 -31
- data/lib/capybara/minitest/spec.rb +185 -83
- data/lib/capybara/minitest.rb +232 -112
- data/lib/capybara/node/actions.rb +274 -171
- data/lib/capybara/node/base.rb +42 -34
- data/lib/capybara/node/document.rb +15 -3
- data/lib/capybara/node/document_matchers.rb +19 -21
- data/lib/capybara/node/element.rb +362 -135
- data/lib/capybara/node/finders.rb +151 -137
- data/lib/capybara/node/matchers.rb +394 -209
- data/lib/capybara/node/simple.rb +59 -26
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +12 -9
- data/lib/capybara/queries/base_query.rb +39 -28
- data/lib/capybara/queries/current_path_query.rb +21 -27
- data/lib/capybara/queries/match_query.rb +14 -7
- data/lib/capybara/queries/selector_query.rb +659 -149
- data/lib/capybara/queries/sibling_query.rb +11 -9
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +56 -38
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +114 -42
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +22 -17
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +93 -58
- data/lib/capybara/rack_test/node.rb +184 -81
- data/lib/capybara/rails.rb +3 -7
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +97 -63
- data/lib/capybara/rspec/features.rb +17 -50
- data/lib/capybara/rspec/matcher_proxies.rb +52 -15
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +146 -310
- data/lib/capybara/rspec.rb +7 -11
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +85 -13
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +2 -17
- data/lib/capybara/selector/filter_set.rb +80 -33
- data/lib/capybara/selector/filters/base.rb +50 -6
- data/lib/capybara/selector/filters/expression_filter.rb +8 -26
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -12
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +93 -210
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +475 -523
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +298 -267
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +517 -145
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +80 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +59 -67
- data/lib/capybara/session/config.rb +81 -67
- data/lib/capybara/session/matchers.rb +28 -20
- data/lib/capybara/session.rb +337 -365
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +151 -12
- data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +161 -57
- data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +22 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +117 -55
- data/lib/capybara/spec/session/choose_spec.rb +64 -31
- data/lib/capybara/spec/session/click_button_spec.rb +231 -173
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
- data/lib/capybara/spec/session/click_link_spec.rb +93 -58
- data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
- data/lib/capybara/spec/session/current_url_spec.rb +57 -39
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
- data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
- data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
- data/lib/capybara/spec/session/find_button_spec.rb +25 -24
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +37 -41
- data/lib/capybara/spec/session/find_link_spec.rb +46 -17
- data/lib/capybara/spec/session/find_spec.rb +260 -145
- data/lib/capybara/spec/session/first_spec.rb +80 -52
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +33 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
- 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 +31 -31
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +100 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +139 -59
- data/lib/capybara/spec/session/has_link_spec.rb +47 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
- data/lib/capybara/spec/session/has_select_spec.rb +107 -72
- data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +183 -5
- data/lib/capybara/spec/session/has_text_spec.rb +106 -62
- data/lib/capybara/spec/session/has_title_spec.rb +20 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +1024 -153
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +12 -6
- data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +107 -81
- data/lib/capybara/spec/session/selectors_spec.rb +52 -19
- data/lib/capybara/spec/session/sibling_spec.rb +10 -10
- data/lib/capybara/spec/session/text_spec.rb +37 -21
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
- data/lib/capybara/spec/session/unselect_spec.rb +39 -38
- data/lib/capybara/spec/session/visit_spec.rb +85 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
- data/lib/capybara/spec/session/window/window_spec.rb +97 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
- data/lib/capybara/spec/session/within_spec.rb +83 -44
- data/lib/capybara/spec/spec_helper.rb +54 -44
- data/lib/capybara/spec/test_app.rb +158 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +163 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +68 -1
- data/lib/capybara/spec/views/with_animation.erb +81 -0
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +69 -12
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +30 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +21 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +5 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +36 -34
- data/lib/capybara.rb +134 -107
- data/spec/basic_node_spec.rb +60 -34
- data/spec/capybara_spec.rb +63 -88
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +85 -64
- data/spec/filter_set_spec.rb +27 -9
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
- data/spec/minitest_spec.rb +52 -7
- data/spec/minitest_spec_spec.rb +94 -63
- data/spec/per_session_config_spec.rb +14 -13
- data/spec/rack_test_spec.rb +194 -125
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +111 -50
- data/spec/rspec/features_spec.rb +37 -31
- data/spec/rspec/scenarios_spec.rb +10 -8
- data/spec/rspec/shared_spec_matchers.rb +473 -422
- data/spec/rspec/views_spec.rb +5 -3
- data/spec/rspec_matchers_spec.rb +52 -11
- data/spec/rspec_spec.rb +109 -89
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +397 -68
- data/spec/selenium_spec_chrome.rb +187 -40
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +60 -0
- data/spec/selenium_spec_firefox.rb +201 -41
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +149 -0
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +213 -102
- data/spec/session_spec.rb +53 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +473 -122
- data/spec/spec_helper.rb +126 -7
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +355 -73
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/rspec/compound.rb +0 -95
- data/lib/capybara/spec/session/assert_current_path.rb +0 -72
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -234
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -127
|
@@ -1,521 +1,569 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'spec_helper'
|
|
3
4
|
require 'capybara/dsl'
|
|
4
5
|
require 'capybara/rspec/matchers'
|
|
5
6
|
require 'benchmark'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
# rubocop:disable RSpec/ExpectActual
|
|
8
9
|
|
|
10
|
+
RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
|
|
9
11
|
include Capybara::DSL
|
|
10
12
|
include Capybara::RSpecMatchers
|
|
11
13
|
|
|
12
|
-
describe
|
|
13
|
-
it
|
|
14
|
-
expect(have_css('h1').description).to eq(
|
|
14
|
+
describe 'have_css matcher' do
|
|
15
|
+
it 'gives proper description' do
|
|
16
|
+
expect(have_css('h1').description).to eq('have visible css "h1"')
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
context
|
|
18
|
-
context
|
|
19
|
-
it
|
|
20
|
-
expect(
|
|
19
|
+
context 'on a string' do
|
|
20
|
+
context 'with should' do
|
|
21
|
+
it 'passes if has_css? returns true' do
|
|
22
|
+
expect('<h1>Text</h1>').to have_css('h1')
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
it
|
|
25
|
+
it 'fails if has_css? returns false' do
|
|
24
26
|
expect do
|
|
25
|
-
expect(
|
|
26
|
-
end.to raise_error(/expected to find
|
|
27
|
+
expect('<h1>Text</h1>').to have_css('h2')
|
|
28
|
+
end.to raise_error(/expected to find css "h2" but there were no matches/)
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
it
|
|
30
|
-
expect(
|
|
31
|
+
it 'passes if matched node count equals expected count' do
|
|
32
|
+
expect('<h1>Text</h1>').to have_css('h1', count: 1)
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
it
|
|
35
|
+
it 'fails if matched node count does not equal expected count' do
|
|
34
36
|
expect do
|
|
35
|
-
expect(
|
|
36
|
-
end.to raise_error(
|
|
37
|
+
expect('<h1>Text</h1>').to have_css('h1', count: 2)
|
|
38
|
+
end.to raise_error('expected to find visible css "h1" 2 times, found 1 match: "Text"')
|
|
37
39
|
end
|
|
38
40
|
|
|
39
|
-
it
|
|
41
|
+
it 'fails if matched node count is less than expected minimum count' do
|
|
40
42
|
expect do
|
|
41
|
-
expect(
|
|
42
|
-
end.to raise_error(
|
|
43
|
+
expect('<h1>Text</h1>').to have_css('p', minimum: 1)
|
|
44
|
+
end.to raise_error('expected to find css "p" at least 1 time but there were no matches')
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
it
|
|
47
|
+
it 'fails if matched node count is more than expected maximum count' do
|
|
46
48
|
expect do
|
|
47
|
-
expect(
|
|
49
|
+
expect('<h1>Text</h1><h1>Text</h1><h1>Text</h1>').to have_css('h1', maximum: 2)
|
|
48
50
|
end.to raise_error('expected to find visible css "h1" at most 2 times, found 3 matches: "Text", "Text", "Text"')
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
it
|
|
53
|
+
it 'fails if matched node count does not belong to expected range' do
|
|
52
54
|
expect do
|
|
53
|
-
expect(
|
|
54
|
-
end.to raise_error(
|
|
55
|
+
expect('<h1>Text</h1>').to have_css('h1', between: 2..3)
|
|
56
|
+
end.to raise_error('expected to find visible css "h1" between 2 and 3 times, found 1 match: "Text"')
|
|
55
57
|
end
|
|
56
|
-
|
|
57
58
|
end
|
|
58
59
|
|
|
59
|
-
context
|
|
60
|
-
it
|
|
61
|
-
expect(
|
|
60
|
+
context 'with should_not' do
|
|
61
|
+
it 'passes if has_no_css? returns true' do
|
|
62
|
+
expect('<h1>Text</h1>').not_to have_css('h2')
|
|
62
63
|
end
|
|
63
64
|
|
|
64
|
-
it
|
|
65
|
+
it 'fails if has_no_css? returns false' do
|
|
65
66
|
expect do
|
|
66
|
-
expect(
|
|
67
|
+
expect('<h1>Text</h1>').not_to have_css('h1')
|
|
67
68
|
end.to raise_error(/expected not to find visible css "h1"/)
|
|
68
69
|
end
|
|
69
70
|
|
|
70
|
-
it
|
|
71
|
-
expect(
|
|
71
|
+
it 'passes if matched node count does not equal expected count' do
|
|
72
|
+
expect('<h1>Text</h1>').not_to have_css('h1', count: 2)
|
|
72
73
|
end
|
|
73
74
|
|
|
74
|
-
it
|
|
75
|
+
it 'fails if matched node count equals expected count' do
|
|
75
76
|
expect do
|
|
76
|
-
expect(
|
|
77
|
+
expect('<h1>Text</h1>').not_to have_css('h1', count: 1)
|
|
77
78
|
end.to raise_error(/expected not to find visible css "h1"/)
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
it
|
|
82
|
-
expect(
|
|
83
|
-
expect(
|
|
84
|
-
|
|
82
|
+
it 'supports compounding' do
|
|
83
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_css('h1').and have_css('h2')
|
|
84
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_css('h3').or have_css('h1')
|
|
85
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_no_css('h4').and have_css('h2')
|
|
86
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_no_css('h2').or have_css('h1')
|
|
87
|
+
end
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
context
|
|
90
|
+
context 'on a page or node' do
|
|
88
91
|
before do
|
|
89
|
-
visit('/with_html')
|
|
92
|
+
session.visit('/with_html')
|
|
90
93
|
end
|
|
91
94
|
|
|
92
|
-
context
|
|
93
|
-
it
|
|
94
|
-
expect(
|
|
95
|
+
context 'with should' do
|
|
96
|
+
it 'passes if has_css? returns true' do
|
|
97
|
+
expect(session).to have_css('h1')
|
|
95
98
|
end
|
|
96
99
|
|
|
97
|
-
it
|
|
100
|
+
it 'fails if has_css? returns false' do
|
|
98
101
|
expect do
|
|
99
|
-
expect(
|
|
100
|
-
end.to raise_error(/expected to find
|
|
102
|
+
expect(session).to have_css('h1#doesnotexist')
|
|
103
|
+
end.to raise_error(/expected to find css "h1#doesnotexist" but there were no matches/)
|
|
101
104
|
end
|
|
102
105
|
end
|
|
103
106
|
|
|
104
|
-
context
|
|
105
|
-
it
|
|
106
|
-
expect(
|
|
107
|
+
context 'with should_not' do
|
|
108
|
+
it 'passes if has_no_css? returns true' do
|
|
109
|
+
expect(session).not_to have_css('h1#doesnotexist')
|
|
107
110
|
end
|
|
108
111
|
|
|
109
|
-
it
|
|
112
|
+
it 'fails if has_no_css? returns false' do
|
|
110
113
|
expect do
|
|
111
|
-
expect(
|
|
114
|
+
expect(session).not_to have_css('h1')
|
|
112
115
|
end.to raise_error(/expected not to find visible css "h1"/)
|
|
113
116
|
end
|
|
114
117
|
end
|
|
115
118
|
end
|
|
116
119
|
end
|
|
117
120
|
|
|
118
|
-
describe
|
|
119
|
-
it
|
|
120
|
-
expect(have_xpath('//h1').description).to eq(
|
|
121
|
+
describe 'have_xpath matcher' do
|
|
122
|
+
it 'gives proper description' do
|
|
123
|
+
expect(have_xpath('//h1').description).to eq('have visible xpath "//h1"')
|
|
121
124
|
end
|
|
122
125
|
|
|
123
|
-
context
|
|
124
|
-
context
|
|
125
|
-
it
|
|
126
|
-
expect(
|
|
126
|
+
context 'on a string' do
|
|
127
|
+
context 'with should' do
|
|
128
|
+
it 'passes if has_xpath? returns true' do
|
|
129
|
+
expect('<h1>Text</h1>').to have_xpath('//h1')
|
|
127
130
|
end
|
|
128
131
|
|
|
129
|
-
it
|
|
132
|
+
it 'fails if has_xpath? returns false' do
|
|
130
133
|
expect do
|
|
131
|
-
expect(
|
|
132
|
-
end.to raise_error(%r
|
|
134
|
+
expect('<h1>Text</h1>').to have_xpath('//h2')
|
|
135
|
+
end.to raise_error(%r{expected to find xpath "//h2" but there were no matches})
|
|
133
136
|
end
|
|
134
137
|
end
|
|
135
138
|
|
|
136
|
-
context
|
|
137
|
-
it
|
|
138
|
-
expect(
|
|
139
|
+
context 'with should_not' do
|
|
140
|
+
it 'passes if has_no_xpath? returns true' do
|
|
141
|
+
expect('<h1>Text</h1>').not_to have_xpath('//h2')
|
|
139
142
|
end
|
|
140
143
|
|
|
141
|
-
it
|
|
144
|
+
it 'fails if has_no_xpath? returns false' do
|
|
142
145
|
expect do
|
|
143
|
-
expect(
|
|
144
|
-
end.to raise_error(%r
|
|
146
|
+
expect('<h1>Text</h1>').not_to have_xpath('//h1')
|
|
147
|
+
end.to raise_error(%r{expected not to find visible xpath "//h1"})
|
|
145
148
|
end
|
|
146
149
|
end
|
|
147
150
|
|
|
148
|
-
it
|
|
149
|
-
expect(
|
|
150
|
-
expect(
|
|
151
|
-
|
|
151
|
+
it 'supports compounding' do
|
|
152
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_xpath('//h1').and have_xpath('//h2')
|
|
153
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_xpath('//h3').or have_xpath('//h1')
|
|
154
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_no_xpath('//h4').and have_xpath('//h1')
|
|
155
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_no_xpath('//h4').or have_xpath('//h4')
|
|
156
|
+
end
|
|
152
157
|
end
|
|
153
158
|
|
|
154
|
-
context
|
|
159
|
+
context 'on a page or node' do
|
|
155
160
|
before do
|
|
156
|
-
visit('/with_html')
|
|
161
|
+
session.visit('/with_html')
|
|
157
162
|
end
|
|
158
163
|
|
|
159
|
-
context
|
|
160
|
-
it
|
|
161
|
-
expect(
|
|
164
|
+
context 'with should' do
|
|
165
|
+
it 'passes if has_xpath? returns true' do
|
|
166
|
+
expect(session).to have_xpath('//h1')
|
|
162
167
|
end
|
|
163
168
|
|
|
164
|
-
it
|
|
169
|
+
it 'fails if has_xpath? returns false' do
|
|
165
170
|
expect do
|
|
166
|
-
expect(
|
|
167
|
-
end.to raise_error(%r
|
|
171
|
+
expect(session).to have_xpath("//h1[@id='doesnotexist']")
|
|
172
|
+
end.to raise_error(%r{expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches})
|
|
168
173
|
end
|
|
169
174
|
end
|
|
170
175
|
|
|
171
|
-
context
|
|
172
|
-
it
|
|
173
|
-
expect(
|
|
176
|
+
context 'with should_not' do
|
|
177
|
+
it 'passes if has_no_xpath? returns true' do
|
|
178
|
+
expect(session).not_to have_xpath('//h1[@id="doesnotexist"]')
|
|
174
179
|
end
|
|
175
180
|
|
|
176
|
-
it
|
|
181
|
+
it 'fails if has_no_xpath? returns false' do
|
|
177
182
|
expect do
|
|
178
|
-
expect(
|
|
179
|
-
end.to raise_error(%r
|
|
183
|
+
expect(session).not_to have_xpath('//h1')
|
|
184
|
+
end.to raise_error(%r{expected not to find visible xpath "//h1"})
|
|
180
185
|
end
|
|
181
186
|
end
|
|
182
187
|
end
|
|
183
188
|
end
|
|
184
189
|
|
|
185
|
-
describe
|
|
186
|
-
it
|
|
190
|
+
describe 'have_selector matcher' do
|
|
191
|
+
it 'gives proper description' do
|
|
187
192
|
matcher = have_selector('//h1')
|
|
188
|
-
expect(
|
|
189
|
-
expect(matcher.description).to eq(
|
|
193
|
+
expect('<h1>Text</h1>').to matcher
|
|
194
|
+
expect(matcher.description).to eq('have visible xpath "//h1"')
|
|
190
195
|
end
|
|
191
196
|
|
|
192
|
-
context
|
|
193
|
-
context
|
|
194
|
-
it
|
|
195
|
-
expect(
|
|
197
|
+
context 'on a string' do
|
|
198
|
+
context 'with should' do
|
|
199
|
+
it 'passes if has_selector? returns true' do
|
|
200
|
+
expect('<h1>Text</h1>').to have_selector('//h1')
|
|
196
201
|
end
|
|
197
202
|
|
|
198
|
-
it
|
|
203
|
+
it 'fails if has_selector? returns false' do
|
|
199
204
|
expect do
|
|
200
|
-
expect(
|
|
201
|
-
end.to raise_error(%r
|
|
205
|
+
expect('<h1>Text</h1>').to have_selector('//h2')
|
|
206
|
+
end.to raise_error(%r{expected to find xpath "//h2" but there were no matches})
|
|
202
207
|
end
|
|
203
208
|
end
|
|
204
209
|
|
|
205
|
-
context
|
|
206
|
-
it
|
|
207
|
-
expect(
|
|
210
|
+
context 'with should_not' do
|
|
211
|
+
it 'passes if has_no_selector? returns true' do
|
|
212
|
+
expect('<h1>Text</h1>').not_to have_selector(:css, 'h2')
|
|
208
213
|
end
|
|
209
214
|
|
|
210
|
-
it
|
|
215
|
+
it 'fails if has_no_selector? returns false' do
|
|
211
216
|
expect do
|
|
212
|
-
expect(
|
|
213
|
-
end.to raise_error(
|
|
217
|
+
expect('<h1>Text</h1>').not_to have_selector(:css, 'h1')
|
|
218
|
+
end.to raise_error(/expected not to find visible css "h1"/)
|
|
214
219
|
end
|
|
215
220
|
end
|
|
216
221
|
end
|
|
217
222
|
|
|
218
|
-
context
|
|
223
|
+
context 'on a page or node' do
|
|
219
224
|
before do
|
|
220
|
-
visit('/with_html')
|
|
225
|
+
session.visit('/with_html')
|
|
221
226
|
end
|
|
222
227
|
|
|
223
|
-
context
|
|
224
|
-
it
|
|
225
|
-
expect(
|
|
228
|
+
context 'with should' do
|
|
229
|
+
it 'passes if has_selector? returns true' do
|
|
230
|
+
expect(session).to have_selector('//h1', text: 'test')
|
|
226
231
|
end
|
|
227
232
|
|
|
228
|
-
it
|
|
233
|
+
it 'fails if has_selector? returns false' do
|
|
229
234
|
expect do
|
|
230
|
-
expect(
|
|
231
|
-
end.to raise_error(%r
|
|
235
|
+
expect(session).to have_selector("//h1[@id='doesnotexist']")
|
|
236
|
+
end.to raise_error(%r{expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches})
|
|
232
237
|
end
|
|
233
238
|
|
|
234
|
-
it
|
|
239
|
+
it 'includes text in error message' do
|
|
235
240
|
expect do
|
|
236
|
-
expect(
|
|
237
|
-
end.to raise_error(%r
|
|
241
|
+
expect(session).to have_selector('//h1', text: 'wrong text')
|
|
242
|
+
end.to raise_error(%r{expected to find visible xpath "//h1" with text "wrong text" but there were no matches})
|
|
238
243
|
end
|
|
239
244
|
end
|
|
240
245
|
|
|
241
|
-
context
|
|
242
|
-
it
|
|
243
|
-
expect(
|
|
246
|
+
context 'with should_not' do
|
|
247
|
+
it 'passes if has_no_css? returns true' do
|
|
248
|
+
expect(session).not_to have_selector(:css, 'h1#doesnotexist')
|
|
244
249
|
end
|
|
245
250
|
|
|
246
|
-
it
|
|
251
|
+
it 'fails if has_no_selector? returns false' do
|
|
247
252
|
expect do
|
|
248
|
-
expect(
|
|
249
|
-
end.to raise_error(
|
|
253
|
+
expect(session).not_to have_selector(:css, 'h1', text: 'test')
|
|
254
|
+
end.to raise_error(/expected not to find visible css "h1" with text "test"/)
|
|
250
255
|
end
|
|
251
256
|
end
|
|
252
257
|
end
|
|
253
258
|
|
|
254
|
-
it
|
|
255
|
-
expect(
|
|
256
|
-
expect(
|
|
257
|
-
|
|
259
|
+
it 'supports compounding' do
|
|
260
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_selector('//h1').and have_selector('//h2')
|
|
261
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_selector('//h3').or have_selector('//h1')
|
|
262
|
+
expect('<h1>Text</h1><h2>Text</h2>').to have_no_selector('//h3').and have_selector('//h1')
|
|
263
|
+
end
|
|
258
264
|
end
|
|
259
265
|
|
|
260
|
-
describe
|
|
261
|
-
it
|
|
262
|
-
expect(have_content('Text').description).to eq(
|
|
266
|
+
describe 'have_content matcher' do
|
|
267
|
+
it 'gives proper description' do
|
|
268
|
+
expect(have_content('Text').description).to eq('have text "Text"')
|
|
263
269
|
end
|
|
264
270
|
|
|
265
|
-
context
|
|
266
|
-
context
|
|
267
|
-
it
|
|
268
|
-
expect(
|
|
271
|
+
context 'on a string' do
|
|
272
|
+
context 'with should' do
|
|
273
|
+
it 'passes if has_content? returns true' do
|
|
274
|
+
expect('<h1>Text</h1>').to have_content('Text')
|
|
269
275
|
end
|
|
270
276
|
|
|
271
|
-
it
|
|
272
|
-
expect(
|
|
277
|
+
it 'passes if has_content? returns true using regexp' do
|
|
278
|
+
expect('<h1>Text</h1>').to have_content(/ext/)
|
|
273
279
|
end
|
|
274
280
|
|
|
275
|
-
it
|
|
281
|
+
it 'fails if has_content? returns false' do
|
|
276
282
|
expect do
|
|
277
|
-
expect(
|
|
283
|
+
expect('<h1>Text</h1>').to have_content('No such Text')
|
|
278
284
|
end.to raise_error(/expected to find text "No such Text" in "Text"/)
|
|
279
285
|
end
|
|
280
286
|
end
|
|
281
287
|
|
|
282
|
-
context
|
|
283
|
-
it
|
|
284
|
-
expect(
|
|
288
|
+
context 'with should_not' do
|
|
289
|
+
it 'passes if has_no_content? returns true' do
|
|
290
|
+
expect('<h1>Text</h1>').not_to have_content('No such Text')
|
|
285
291
|
end
|
|
286
292
|
|
|
287
|
-
it
|
|
288
|
-
expect(
|
|
293
|
+
it 'passes because escapes any characters that would have special meaning in a regexp' do
|
|
294
|
+
expect('<h1>Text</h1>').not_to have_content('.')
|
|
289
295
|
end
|
|
290
296
|
|
|
291
|
-
it
|
|
297
|
+
it 'fails if has_no_content? returns false' do
|
|
292
298
|
expect do
|
|
293
|
-
expect(
|
|
299
|
+
expect('<h1>Text</h1>').not_to have_content('Text')
|
|
294
300
|
end.to raise_error(/expected not to find text "Text" in "Text"/)
|
|
295
301
|
end
|
|
296
302
|
end
|
|
297
303
|
end
|
|
298
304
|
|
|
299
|
-
context
|
|
305
|
+
context 'on a page or node' do
|
|
300
306
|
before do
|
|
301
|
-
visit('/with_html')
|
|
307
|
+
session.visit('/with_html')
|
|
302
308
|
end
|
|
303
309
|
|
|
304
|
-
context
|
|
305
|
-
it
|
|
306
|
-
expect(
|
|
310
|
+
context 'with should' do
|
|
311
|
+
it 'passes if has_content? returns true' do
|
|
312
|
+
expect(session).to have_content('This is a test')
|
|
307
313
|
end
|
|
308
314
|
|
|
309
|
-
it
|
|
310
|
-
expect(
|
|
315
|
+
it 'passes if has_content? returns true using regexp' do
|
|
316
|
+
expect(session).to have_content(/test/)
|
|
311
317
|
end
|
|
312
318
|
|
|
313
|
-
it
|
|
319
|
+
it 'fails if has_content? returns false' do
|
|
314
320
|
expect do
|
|
315
|
-
expect(
|
|
321
|
+
expect(session).to have_content('No such Text')
|
|
316
322
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
317
323
|
end
|
|
318
324
|
|
|
319
|
-
context
|
|
325
|
+
context 'with default selector CSS' do
|
|
320
326
|
before { Capybara.default_selector = :css }
|
|
321
|
-
|
|
327
|
+
|
|
328
|
+
after { Capybara.default_selector = :xpath }
|
|
329
|
+
|
|
330
|
+
it 'fails if has_content? returns false' do
|
|
322
331
|
expect do
|
|
323
|
-
expect(
|
|
332
|
+
expect(session).to have_content('No such Text')
|
|
324
333
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
325
334
|
end
|
|
326
|
-
after { Capybara.default_selector = :xpath }
|
|
327
335
|
end
|
|
328
336
|
end
|
|
329
337
|
|
|
330
|
-
context
|
|
331
|
-
it
|
|
332
|
-
expect(
|
|
338
|
+
context 'with should_not' do
|
|
339
|
+
it 'passes if has_no_content? returns true' do
|
|
340
|
+
expect(session).not_to have_content('No such Text')
|
|
333
341
|
end
|
|
334
342
|
|
|
335
|
-
it
|
|
343
|
+
it 'fails if has_no_content? returns false' do
|
|
336
344
|
expect do
|
|
337
|
-
expect(
|
|
345
|
+
expect(session).not_to have_content('This is a test')
|
|
338
346
|
end.to raise_error(/expected not to find text "This is a test"/)
|
|
339
347
|
end
|
|
348
|
+
|
|
349
|
+
it 'not_to have_content behaves the same as to have_no_content' do
|
|
350
|
+
Capybara.using_wait_time(5) do
|
|
351
|
+
expect(session).to have_content('This is a test')
|
|
352
|
+
start = Time.now
|
|
353
|
+
expect(session).to have_no_content('No such Text')
|
|
354
|
+
to_time = Time.now
|
|
355
|
+
expect(session).not_to have_content('No such Text')
|
|
356
|
+
not_to_time = Time.now
|
|
357
|
+
expect(not_to_time - to_time).to be_within(0.5).of(to_time - start)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
340
360
|
end
|
|
341
361
|
end
|
|
342
362
|
|
|
343
|
-
it
|
|
344
|
-
expect(
|
|
345
|
-
expect(
|
|
346
|
-
|
|
363
|
+
it 'supports compounding' do
|
|
364
|
+
expect('<h1>Text</h1><h2>And</h2>').to have_content('Text').and have_content('And')
|
|
365
|
+
expect('<h1>Text</h1><h2>Or</h2>').to have_content('XYZ').or have_content('Or')
|
|
366
|
+
expect('<h1>Text</h1><h2>Or</h2>').to have_no_content('XYZ').and have_content('Or')
|
|
367
|
+
end
|
|
347
368
|
end
|
|
348
369
|
|
|
349
|
-
describe
|
|
350
|
-
it
|
|
351
|
-
expect(have_text('Text').description).to eq(
|
|
370
|
+
describe 'have_text matcher' do
|
|
371
|
+
it 'gives proper description' do
|
|
372
|
+
expect(have_text('Text').description).to eq('have text "Text"')
|
|
352
373
|
end
|
|
353
374
|
|
|
354
|
-
context
|
|
355
|
-
context
|
|
356
|
-
it
|
|
357
|
-
expect(
|
|
375
|
+
context 'on a string' do
|
|
376
|
+
context 'with should' do
|
|
377
|
+
it 'passes if text contains given string' do
|
|
378
|
+
expect('<h1>Text</h1>').to have_text('Text')
|
|
358
379
|
end
|
|
359
380
|
|
|
360
|
-
it
|
|
361
|
-
expect(
|
|
381
|
+
it 'passes if text matches given regexp' do
|
|
382
|
+
expect('<h1>Text</h1>').to have_text(/ext/)
|
|
362
383
|
end
|
|
363
384
|
|
|
364
385
|
it "fails if text doesn't contain given string" do
|
|
365
386
|
expect do
|
|
366
|
-
expect(
|
|
387
|
+
expect('<h1>Text</h1>').to have_text('No such Text')
|
|
367
388
|
end.to raise_error(/expected to find text "No such Text" in "Text"/)
|
|
368
389
|
end
|
|
369
390
|
|
|
370
391
|
it "fails if text doesn't match given regexp" do
|
|
371
392
|
expect do
|
|
372
|
-
expect(
|
|
393
|
+
expect('<h1>Text</h1>').to have_text(/No such Text/)
|
|
373
394
|
end.to raise_error('expected to find text matching /No such Text/ in "Text"')
|
|
374
395
|
end
|
|
375
396
|
|
|
376
|
-
it
|
|
397
|
+
it 'casts Integer to string' do
|
|
377
398
|
expect do
|
|
378
|
-
expect(
|
|
399
|
+
expect('<h1>Text</h1>').to have_text(3)
|
|
379
400
|
end.to raise_error(/expected to find text "3" in "Text"/)
|
|
380
401
|
end
|
|
381
402
|
|
|
382
|
-
it
|
|
403
|
+
it 'fails if matched text count does not equal to expected count' do
|
|
383
404
|
expect do
|
|
384
|
-
expect(
|
|
405
|
+
expect('<h1>Text</h1>').to have_text('Text', count: 2)
|
|
385
406
|
end.to raise_error('expected to find text "Text" 2 times but found 1 time in "Text"')
|
|
386
407
|
end
|
|
387
408
|
|
|
388
|
-
it
|
|
409
|
+
it 'fails if matched text count is less than expected minimum count' do
|
|
389
410
|
expect do
|
|
390
|
-
expect(
|
|
411
|
+
expect('<h1>Text</h1>').to have_text('Lorem', minimum: 1)
|
|
391
412
|
end.to raise_error('expected to find text "Lorem" at least 1 time but found 0 times in "Text"')
|
|
392
413
|
end
|
|
393
414
|
|
|
394
|
-
it
|
|
415
|
+
it 'fails if matched text count is more than expected maximum count' do
|
|
395
416
|
expect do
|
|
396
|
-
expect(
|
|
417
|
+
expect('<h1>Text TextText</h1>').to have_text('Text', maximum: 2)
|
|
397
418
|
end.to raise_error('expected to find text "Text" at most 2 times but found 3 times in "Text TextText"')
|
|
398
419
|
end
|
|
399
420
|
|
|
400
|
-
it
|
|
421
|
+
it 'fails if matched text count does not belong to expected range' do
|
|
401
422
|
expect do
|
|
402
|
-
expect(
|
|
423
|
+
expect('<h1>Text</h1>').to have_text('Text', between: 2..3)
|
|
403
424
|
end.to raise_error('expected to find text "Text" between 2 and 3 times but found 1 time in "Text"')
|
|
404
425
|
end
|
|
405
426
|
end
|
|
406
427
|
|
|
407
|
-
context
|
|
428
|
+
context 'with should_not' do
|
|
408
429
|
it "passes if text doesn't contain a string" do
|
|
409
|
-
expect(
|
|
430
|
+
expect('<h1>Text</h1>').not_to have_text('No such Text')
|
|
410
431
|
end
|
|
411
432
|
|
|
412
|
-
it
|
|
413
|
-
expect(
|
|
433
|
+
it 'passes because escapes any characters that would have special meaning in a regexp' do
|
|
434
|
+
expect('<h1>Text</h1>').not_to have_text('.')
|
|
414
435
|
end
|
|
415
436
|
|
|
416
|
-
it
|
|
437
|
+
it 'fails if text contains a string' do
|
|
417
438
|
expect do
|
|
418
|
-
expect(
|
|
439
|
+
expect('<h1>Text</h1>').not_to have_text('Text')
|
|
419
440
|
end.to raise_error(/expected not to find text "Text" in "Text"/)
|
|
420
441
|
end
|
|
421
442
|
end
|
|
422
443
|
end
|
|
423
444
|
|
|
424
|
-
context
|
|
445
|
+
context 'on a page or node' do
|
|
425
446
|
before do
|
|
426
|
-
visit('/with_html')
|
|
447
|
+
session.visit('/with_html')
|
|
427
448
|
end
|
|
428
449
|
|
|
429
|
-
context
|
|
430
|
-
it
|
|
431
|
-
expect(
|
|
450
|
+
context 'with should' do
|
|
451
|
+
it 'passes if has_text? returns true' do
|
|
452
|
+
expect(session).to have_text('This is a test')
|
|
432
453
|
end
|
|
433
454
|
|
|
434
|
-
it
|
|
435
|
-
expect(
|
|
455
|
+
it 'passes if has_text? returns true using regexp' do
|
|
456
|
+
expect(session).to have_text(/test/)
|
|
436
457
|
end
|
|
437
458
|
|
|
438
|
-
it
|
|
439
|
-
expect(
|
|
459
|
+
it 'can check for all text' do
|
|
460
|
+
expect(session).to have_text(:all, 'Some of this text is hidden!')
|
|
440
461
|
end
|
|
441
462
|
|
|
442
|
-
it
|
|
443
|
-
expect(
|
|
444
|
-
expect(
|
|
463
|
+
it 'can check for visible text' do
|
|
464
|
+
expect(session).to have_text(:visible, 'Some of this text is')
|
|
465
|
+
expect(session).not_to have_text(:visible, 'Some of this text is hidden!')
|
|
445
466
|
end
|
|
446
467
|
|
|
447
|
-
it
|
|
468
|
+
it 'fails if has_text? returns false' do
|
|
448
469
|
expect do
|
|
449
|
-
expect(
|
|
470
|
+
expect(session).to have_text('No such Text')
|
|
450
471
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
451
472
|
end
|
|
452
473
|
|
|
453
|
-
context
|
|
474
|
+
context 'with default selector CSS' do
|
|
454
475
|
before { Capybara.default_selector = :css }
|
|
455
|
-
|
|
476
|
+
|
|
477
|
+
after { Capybara.default_selector = :xpath }
|
|
478
|
+
|
|
479
|
+
it 'fails if has_text? returns false' do
|
|
456
480
|
expect do
|
|
457
|
-
expect(
|
|
481
|
+
expect(session).to have_text('No such Text')
|
|
458
482
|
end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/)
|
|
459
483
|
end
|
|
460
|
-
after { Capybara.default_selector = :xpath }
|
|
461
484
|
end
|
|
462
485
|
end
|
|
463
486
|
|
|
464
|
-
context
|
|
465
|
-
it
|
|
466
|
-
expect(
|
|
487
|
+
context 'with should_not' do
|
|
488
|
+
it 'passes if has_no_text? returns true' do
|
|
489
|
+
expect(session).not_to have_text('No such Text')
|
|
467
490
|
end
|
|
468
491
|
|
|
469
|
-
it
|
|
492
|
+
it 'fails if has_no_text? returns false' do
|
|
470
493
|
expect do
|
|
471
|
-
expect(
|
|
494
|
+
expect(session).not_to have_text('This is a test')
|
|
472
495
|
end.to raise_error(/expected not to find text "This is a test"/)
|
|
473
496
|
end
|
|
474
497
|
end
|
|
475
498
|
end
|
|
476
499
|
|
|
477
|
-
it
|
|
478
|
-
expect(
|
|
479
|
-
expect(
|
|
480
|
-
end
|
|
500
|
+
it 'supports compounding' do
|
|
501
|
+
expect('<h1>Text</h1><h2>And</h2>').to have_text('Text').and have_text('And')
|
|
502
|
+
expect('<h1>Text</h1><h2>Or</h2>').to have_text('Not here').or have_text('Or')
|
|
503
|
+
end
|
|
481
504
|
end
|
|
482
505
|
|
|
483
|
-
describe
|
|
506
|
+
describe 'have_element matcher' do
|
|
507
|
+
let(:html) { '<img src="/img.jpg" alt="a JPEG"><img src="/img.png" alt="a PNG">' }
|
|
508
|
+
|
|
509
|
+
it 'gives proper description' do
|
|
510
|
+
expect(have_element('img').description).to eq('have visible element "img"')
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
it 'passes if there is such a element' do
|
|
514
|
+
expect(html).to have_element('img', src: '/img.jpg')
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it 'fails if there is no such element' do
|
|
518
|
+
expect do
|
|
519
|
+
expect(html).to have_element('photo')
|
|
520
|
+
end.to raise_error(/expected to find element "photo"/)
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it 'supports compounding' do
|
|
524
|
+
expect(html).to have_element('img', alt: 'a JPEG').and have_element('img', src: '/img.png')
|
|
525
|
+
expect(html).to have_element('photo').or have_element('img', src: '/img.jpg')
|
|
526
|
+
expect(html).to have_no_element('photo').and have_element('img', alt: 'a PNG')
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
describe 'have_link matcher' do
|
|
484
531
|
let(:html) { '<a href="#">Just a link</a><a href="#">Another link</a>' }
|
|
485
532
|
|
|
486
|
-
it
|
|
487
|
-
expect(have_link('Just a link').description).to eq(
|
|
533
|
+
it 'gives proper description' do
|
|
534
|
+
expect(have_link('Just a link').description).to eq('have visible link "Just a link"')
|
|
488
535
|
end
|
|
489
536
|
|
|
490
|
-
it
|
|
537
|
+
it 'passes if there is such a link' do
|
|
491
538
|
expect(html).to have_link('Just a link')
|
|
492
539
|
end
|
|
493
540
|
|
|
494
|
-
it
|
|
541
|
+
it 'fails if there is no such link' do
|
|
495
542
|
expect do
|
|
496
543
|
expect(html).to have_link('No such Link')
|
|
497
|
-
end.to raise_error(/expected to find
|
|
544
|
+
end.to raise_error(/expected to find link "No such Link"/)
|
|
498
545
|
end
|
|
499
546
|
|
|
500
|
-
it
|
|
547
|
+
it 'supports compounding' do
|
|
501
548
|
expect(html).to have_link('Just a link').and have_link('Another link')
|
|
502
549
|
expect(html).to have_link('Not a link').or have_link('Another link')
|
|
503
|
-
|
|
550
|
+
expect(html).to have_no_link('Not a link').and have_link('Another link')
|
|
551
|
+
end
|
|
504
552
|
end
|
|
505
553
|
|
|
506
|
-
describe
|
|
507
|
-
it
|
|
508
|
-
expect(have_title('Just a title').description).to eq(
|
|
554
|
+
describe 'have_title matcher' do
|
|
555
|
+
it 'gives proper description' do
|
|
556
|
+
expect(have_title('Just a title').description).to eq('have title "Just a title"')
|
|
509
557
|
end
|
|
510
558
|
|
|
511
|
-
context
|
|
559
|
+
context 'on a string' do
|
|
512
560
|
let(:html) { '<title>Just a title</title>' }
|
|
513
561
|
|
|
514
|
-
it
|
|
562
|
+
it 'passes if there is such a title' do
|
|
515
563
|
expect(html).to have_title('Just a title')
|
|
516
564
|
end
|
|
517
565
|
|
|
518
|
-
it
|
|
566
|
+
it 'fails if there is no such title' do
|
|
519
567
|
expect do
|
|
520
568
|
expect(html).to have_title('No such title')
|
|
521
569
|
end.to raise_error('expected "Just a title" to include "No such title"')
|
|
@@ -528,405 +576,408 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, mode|
|
|
|
528
576
|
end
|
|
529
577
|
end
|
|
530
578
|
|
|
531
|
-
context
|
|
532
|
-
it
|
|
533
|
-
visit('/with_js')
|
|
534
|
-
expect(
|
|
579
|
+
context 'on a page or node' do
|
|
580
|
+
it 'passes if there is such a title' do
|
|
581
|
+
session.visit('/with_js')
|
|
582
|
+
expect(session).to have_title('with_js')
|
|
535
583
|
end
|
|
536
584
|
|
|
537
|
-
it
|
|
538
|
-
visit('/with_js')
|
|
585
|
+
it 'fails if there is no such title' do
|
|
586
|
+
session.visit('/with_js')
|
|
539
587
|
expect do
|
|
540
|
-
expect(
|
|
541
|
-
end.to raise_error(
|
|
588
|
+
expect(session).to have_title('No such title')
|
|
589
|
+
end.to raise_error(/ to include "No such title"/)
|
|
542
590
|
end
|
|
543
591
|
|
|
544
592
|
context 'with wait' do
|
|
545
|
-
before
|
|
546
|
-
|
|
547
|
-
@session.visit('/with_js')
|
|
593
|
+
before do
|
|
594
|
+
session.visit('/with_js')
|
|
548
595
|
end
|
|
549
596
|
|
|
550
597
|
it 'waits if wait time is more than timeout' do
|
|
551
|
-
|
|
552
|
-
using_wait_time 0 do
|
|
553
|
-
expect(
|
|
598
|
+
session.click_link('Change title')
|
|
599
|
+
session.using_wait_time 0 do
|
|
600
|
+
expect(session).to have_title('changed title', wait: 2)
|
|
554
601
|
end
|
|
555
602
|
end
|
|
556
603
|
|
|
557
604
|
it "doesn't wait if wait time is less than timeout" do
|
|
558
|
-
|
|
559
|
-
using_wait_time 3 do
|
|
560
|
-
expect(
|
|
605
|
+
session.click_link('Change title')
|
|
606
|
+
session.using_wait_time 3 do
|
|
607
|
+
expect(session).not_to have_title('changed title', wait: 0)
|
|
561
608
|
end
|
|
562
609
|
end
|
|
563
610
|
end
|
|
564
611
|
end
|
|
565
612
|
|
|
566
|
-
it
|
|
567
|
-
expect(
|
|
568
|
-
end
|
|
613
|
+
it 'supports compounding' do
|
|
614
|
+
expect('<title>I compound</title>').to have_title('I dont compound').or have_title('I compound')
|
|
615
|
+
end
|
|
569
616
|
end
|
|
570
617
|
|
|
571
|
-
describe
|
|
572
|
-
it
|
|
573
|
-
expect(have_current_path('http://www.example.com').description).to eq(
|
|
618
|
+
describe 'have_current_path matcher' do
|
|
619
|
+
it 'gives proper description' do
|
|
620
|
+
expect(have_current_path('http://www.example.com').description).to eq('have current path "http://www.example.com"')
|
|
574
621
|
end
|
|
575
622
|
|
|
576
|
-
context
|
|
577
|
-
it
|
|
578
|
-
visit('/with_js')
|
|
579
|
-
expect(
|
|
623
|
+
context 'on a page or node' do
|
|
624
|
+
it 'passes if there is such a current path' do
|
|
625
|
+
session.visit('/with_js')
|
|
626
|
+
expect(session).to have_current_path('/with_js')
|
|
580
627
|
end
|
|
581
628
|
|
|
582
|
-
it
|
|
629
|
+
it 'fails if there is no such current_path' do
|
|
583
630
|
visit('/with_js')
|
|
584
631
|
expect do
|
|
585
|
-
expect(
|
|
586
|
-
end.to raise_error(
|
|
632
|
+
expect(session).to have_current_path('/not_with_js')
|
|
633
|
+
end.to raise_error(%r{to equal "/not_with_js"})
|
|
587
634
|
end
|
|
588
635
|
|
|
589
636
|
context 'with wait' do
|
|
590
|
-
before
|
|
591
|
-
|
|
592
|
-
@session.visit('/with_js')
|
|
637
|
+
before do
|
|
638
|
+
session.visit('/with_js')
|
|
593
639
|
end
|
|
594
640
|
|
|
595
641
|
it 'waits if wait time is more than timeout' do
|
|
596
|
-
|
|
597
|
-
using_wait_time 0 do
|
|
598
|
-
expect(
|
|
642
|
+
session.click_link('Change page')
|
|
643
|
+
session.using_wait_time 0 do
|
|
644
|
+
expect(session).to have_current_path('/with_html', wait: 2)
|
|
599
645
|
end
|
|
600
646
|
end
|
|
601
647
|
|
|
602
648
|
it "doesn't wait if wait time is less than timeout" do
|
|
603
|
-
|
|
604
|
-
using_wait_time 0 do
|
|
605
|
-
expect(
|
|
649
|
+
session.click_link('Change page')
|
|
650
|
+
session.using_wait_time 0 do
|
|
651
|
+
expect(session).not_to have_current_path('/with_html')
|
|
606
652
|
end
|
|
607
653
|
end
|
|
608
654
|
end
|
|
609
655
|
end
|
|
610
656
|
|
|
611
|
-
it
|
|
612
|
-
visit('/with_html')
|
|
613
|
-
expect(
|
|
614
|
-
end
|
|
657
|
+
it 'supports compounding' do
|
|
658
|
+
session.visit('/with_html')
|
|
659
|
+
expect(session).to have_current_path('/not_with_html').or have_current_path('/with_html')
|
|
660
|
+
end
|
|
615
661
|
end
|
|
616
662
|
|
|
617
|
-
describe
|
|
663
|
+
describe 'have_button matcher' do
|
|
618
664
|
let(:html) { '<button>A button</button><input type="submit" value="Another button"/>' }
|
|
619
665
|
|
|
620
|
-
it
|
|
621
|
-
expect(have_button('A button').description).to eq(
|
|
666
|
+
it 'gives proper description with no options' do
|
|
667
|
+
expect(have_button('A button').description).to eq('have visible button "A button" that is not disabled')
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
it 'gives proper description with disabled :any option' do
|
|
671
|
+
expect(have_button('A button', disabled: :all).description).to eq('have visible button "A button"')
|
|
622
672
|
end
|
|
623
673
|
|
|
624
|
-
it
|
|
674
|
+
it 'passes if there is such a button' do
|
|
625
675
|
expect(html).to have_button('A button')
|
|
626
676
|
end
|
|
627
677
|
|
|
628
|
-
it
|
|
678
|
+
it 'fails if there is no such button' do
|
|
629
679
|
expect do
|
|
630
680
|
expect(html).to have_button('No such Button')
|
|
631
|
-
end.to raise_error(/expected to find
|
|
681
|
+
end.to raise_error(/expected to find button "No such Button"/)
|
|
632
682
|
end
|
|
633
683
|
|
|
634
|
-
it
|
|
684
|
+
it 'supports compounding' do
|
|
635
685
|
expect(html).to have_button('Not this button').or have_button('A button')
|
|
636
|
-
end
|
|
686
|
+
end
|
|
637
687
|
end
|
|
638
688
|
|
|
639
|
-
describe
|
|
689
|
+
describe 'have_field matcher' do
|
|
640
690
|
let(:html) { '<p><label>Text field<input type="text" value="some value"/></label></p>' }
|
|
641
691
|
|
|
642
|
-
it
|
|
643
|
-
expect(have_field('Text field').description).to eq(
|
|
692
|
+
it 'gives proper description' do
|
|
693
|
+
expect(have_field('Text field').description).to eq('have visible field "Text field" that is not disabled')
|
|
644
694
|
end
|
|
645
695
|
|
|
646
|
-
it
|
|
647
|
-
expect(have_field('Text field', with: 'some value').description).to eq(
|
|
696
|
+
it 'gives proper description for a given value' do
|
|
697
|
+
expect(have_field('Text field', with: 'some value').description).to eq('have visible field "Text field" that is not disabled with value "some value"')
|
|
648
698
|
end
|
|
649
699
|
|
|
650
|
-
it
|
|
700
|
+
it 'passes if there is such a field' do
|
|
651
701
|
expect(html).to have_field('Text field')
|
|
652
702
|
end
|
|
653
703
|
|
|
654
|
-
it
|
|
704
|
+
it 'passes if there is such a field with value' do
|
|
655
705
|
expect(html).to have_field('Text field', with: 'some value')
|
|
656
706
|
end
|
|
657
707
|
|
|
658
|
-
it
|
|
708
|
+
it 'fails if there is no such field' do
|
|
659
709
|
expect do
|
|
660
710
|
expect(html).to have_field('No such Field')
|
|
661
|
-
end.to raise_error(/expected to find
|
|
711
|
+
end.to raise_error(/expected to find field "No such Field"/)
|
|
662
712
|
end
|
|
663
713
|
|
|
664
|
-
it
|
|
714
|
+
it 'fails if there is such field but with false value' do
|
|
665
715
|
expect do
|
|
666
716
|
expect(html).to have_field('Text field', with: 'false value')
|
|
667
717
|
end.to raise_error(/expected to find visible field "Text field"/)
|
|
668
718
|
end
|
|
669
719
|
|
|
670
|
-
it
|
|
671
|
-
|
|
720
|
+
it 'treats a given value as a string' do
|
|
721
|
+
foo = Class.new do
|
|
672
722
|
def to_s
|
|
673
|
-
|
|
723
|
+
'some value'
|
|
674
724
|
end
|
|
675
725
|
end
|
|
676
|
-
expect(html).to have_field('Text field', with:
|
|
726
|
+
expect(html).to have_field('Text field', with: foo.new)
|
|
677
727
|
end
|
|
678
728
|
|
|
679
|
-
it
|
|
729
|
+
it 'supports compounding' do
|
|
680
730
|
expect(html).to have_field('Not this one').or have_field('Text field')
|
|
681
|
-
end
|
|
731
|
+
end
|
|
682
732
|
end
|
|
683
733
|
|
|
684
|
-
describe
|
|
734
|
+
describe 'have_checked_field matcher' do
|
|
685
735
|
let(:html) do
|
|
686
736
|
'<label>it is checked<input type="checkbox" checked="checked"/></label>
|
|
687
737
|
<label>unchecked field<input type="checkbox"/></label>'
|
|
688
738
|
end
|
|
689
739
|
|
|
690
|
-
it
|
|
691
|
-
expect(have_checked_field('it is checked').description).to eq(
|
|
740
|
+
it 'gives proper description' do
|
|
741
|
+
expect(have_checked_field('it is checked').description).to eq('have visible field "it is checked" that is not disabled that is checked')
|
|
692
742
|
end
|
|
693
743
|
|
|
694
|
-
context
|
|
695
|
-
it
|
|
744
|
+
context 'with should' do
|
|
745
|
+
it 'passes if there is such a field and it is checked' do
|
|
696
746
|
expect(html).to have_checked_field('it is checked')
|
|
697
747
|
end
|
|
698
748
|
|
|
699
|
-
it
|
|
749
|
+
it 'fails if there is such a field but it is not checked' do
|
|
700
750
|
expect do
|
|
701
751
|
expect(html).to have_checked_field('unchecked field')
|
|
702
752
|
end.to raise_error(/expected to find visible field "unchecked field"/)
|
|
703
753
|
end
|
|
704
754
|
|
|
705
|
-
it
|
|
755
|
+
it 'fails if there is no such field' do
|
|
706
756
|
expect do
|
|
707
757
|
expect(html).to have_checked_field('no such field')
|
|
708
|
-
end.to raise_error(/expected to find
|
|
758
|
+
end.to raise_error(/expected to find field "no such field"/)
|
|
709
759
|
end
|
|
710
760
|
end
|
|
711
761
|
|
|
712
|
-
context
|
|
713
|
-
it
|
|
762
|
+
context 'with should not' do
|
|
763
|
+
it 'fails if there is such a field and it is checked' do
|
|
714
764
|
expect do
|
|
715
765
|
expect(html).not_to have_checked_field('it is checked')
|
|
716
766
|
end.to raise_error(/expected not to find visible field "it is checked"/)
|
|
717
767
|
end
|
|
718
768
|
|
|
719
|
-
it
|
|
769
|
+
it 'passes if there is such a field but it is not checked' do
|
|
720
770
|
expect(html).not_to have_checked_field('unchecked field')
|
|
721
771
|
end
|
|
722
772
|
|
|
723
|
-
it
|
|
773
|
+
it 'passes if there is no such field' do
|
|
724
774
|
expect(html).not_to have_checked_field('no such field')
|
|
725
775
|
end
|
|
726
776
|
end
|
|
727
777
|
|
|
728
|
-
it
|
|
778
|
+
it 'supports compounding' do
|
|
729
779
|
expect(html).to have_checked_field('not this one').or have_checked_field('it is checked')
|
|
730
|
-
end
|
|
780
|
+
end
|
|
731
781
|
end
|
|
732
782
|
|
|
733
|
-
describe
|
|
783
|
+
describe 'have_unchecked_field matcher' do
|
|
734
784
|
let(:html) do
|
|
735
785
|
'<label>it is checked<input type="checkbox" checked="checked"/></label>
|
|
736
786
|
<label>unchecked field<input type="checkbox"/></label>'
|
|
737
787
|
end
|
|
738
788
|
|
|
739
|
-
it
|
|
740
|
-
expect(have_unchecked_field('unchecked field').description).to eq(
|
|
789
|
+
it 'gives proper description' do
|
|
790
|
+
expect(have_unchecked_field('unchecked field').description).to eq('have visible field "unchecked field" that is not disabled that is not checked')
|
|
741
791
|
end
|
|
742
792
|
|
|
743
|
-
context
|
|
744
|
-
it
|
|
793
|
+
context 'with should' do
|
|
794
|
+
it 'passes if there is such a field and it is not checked' do
|
|
745
795
|
expect(html).to have_unchecked_field('unchecked field')
|
|
746
796
|
end
|
|
747
797
|
|
|
748
|
-
it
|
|
798
|
+
it 'fails if there is such a field but it is checked' do
|
|
749
799
|
expect do
|
|
750
800
|
expect(html).to have_unchecked_field('it is checked')
|
|
751
801
|
end.to raise_error(/expected to find visible field "it is checked"/)
|
|
752
802
|
end
|
|
753
803
|
|
|
754
|
-
it
|
|
804
|
+
it 'fails if there is no such field' do
|
|
755
805
|
expect do
|
|
756
806
|
expect(html).to have_unchecked_field('no such field')
|
|
757
|
-
end.to raise_error(/expected to find
|
|
807
|
+
end.to raise_error(/expected to find field "no such field"/)
|
|
758
808
|
end
|
|
759
809
|
end
|
|
760
810
|
|
|
761
|
-
context
|
|
762
|
-
it
|
|
811
|
+
context 'with should not' do
|
|
812
|
+
it 'fails if there is such a field and it is not checked' do
|
|
763
813
|
expect do
|
|
764
814
|
expect(html).not_to have_unchecked_field('unchecked field')
|
|
765
815
|
end.to raise_error(/expected not to find visible field "unchecked field"/)
|
|
766
816
|
end
|
|
767
817
|
|
|
768
|
-
it
|
|
818
|
+
it 'passes if there is such a field but it is checked' do
|
|
769
819
|
expect(html).not_to have_unchecked_field('it is checked')
|
|
770
820
|
end
|
|
771
821
|
|
|
772
|
-
it
|
|
822
|
+
it 'passes if there is no such field' do
|
|
773
823
|
expect(html).not_to have_unchecked_field('no such field')
|
|
774
824
|
end
|
|
775
825
|
end
|
|
776
826
|
|
|
777
|
-
it
|
|
827
|
+
it 'supports compounding' do
|
|
778
828
|
expect(html).to have_unchecked_field('it is checked').or have_unchecked_field('unchecked field')
|
|
779
|
-
end
|
|
829
|
+
end
|
|
780
830
|
end
|
|
781
831
|
|
|
782
|
-
describe
|
|
832
|
+
describe 'have_select matcher' do
|
|
783
833
|
let(:html) { '<label>Select Box<select></select></label>' }
|
|
784
834
|
|
|
785
|
-
it
|
|
786
|
-
expect(have_select('Select Box').description).to eq(
|
|
835
|
+
it 'gives proper description' do
|
|
836
|
+
expect(have_select('Select Box').description).to eq('have visible select box "Select Box" that is not disabled')
|
|
787
837
|
end
|
|
788
838
|
|
|
789
|
-
it
|
|
839
|
+
it 'gives proper description for a given selected value' do
|
|
790
840
|
expect(have_select('Select Box', selected: 'some value').description).to eq('have visible select box "Select Box" that is not disabled with "some value" selected')
|
|
791
841
|
end
|
|
792
842
|
|
|
793
|
-
it
|
|
843
|
+
it 'passes if there is such a select' do
|
|
794
844
|
expect(html).to have_select('Select Box')
|
|
795
845
|
end
|
|
796
846
|
|
|
797
|
-
it
|
|
847
|
+
it 'fails if there is no such select' do
|
|
798
848
|
expect do
|
|
799
849
|
expect(html).to have_select('No such Select box')
|
|
800
|
-
end.to raise_error(/expected to find
|
|
850
|
+
end.to raise_error(/expected to find select box "No such Select box"/)
|
|
801
851
|
end
|
|
802
852
|
|
|
803
|
-
it
|
|
853
|
+
it 'supports compounding' do
|
|
804
854
|
expect(html).to have_select('Not this one').or have_select('Select Box')
|
|
805
|
-
end
|
|
855
|
+
end
|
|
806
856
|
end
|
|
807
857
|
|
|
808
|
-
describe
|
|
858
|
+
describe 'have_table matcher' do
|
|
809
859
|
let(:html) { '<table><caption>Lovely table</caption></table>' }
|
|
810
860
|
|
|
811
|
-
it
|
|
812
|
-
expect(have_table('Lovely table').description).to eq(
|
|
861
|
+
it 'gives proper description' do
|
|
862
|
+
expect(have_table('Lovely table').description).to eq('have visible table "Lovely table"')
|
|
863
|
+
expect(have_table('Lovely table', caption: 'my caption').description).to eq('have visible table "Lovely table" with caption "my caption"')
|
|
813
864
|
end
|
|
814
865
|
|
|
815
|
-
it
|
|
816
|
-
expect(have_table('Lovely table', visible: true).description).to eq(
|
|
817
|
-
expect(have_table('Lovely table', visible: :hidden).description).to eq(
|
|
818
|
-
expect(have_table('Lovely table', visible: :all).description).to eq(
|
|
819
|
-
expect(have_table('Lovely table', visible: false).description).to eq(
|
|
866
|
+
it 'gives proper description when :visible option passed' do
|
|
867
|
+
expect(have_table('Lovely table', visible: true).description).to eq('have visible table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
|
868
|
+
expect(have_table('Lovely table', visible: :hidden).description).to eq('have non-visible table "Lovely table"')
|
|
869
|
+
expect(have_table('Lovely table', visible: :all).description).to eq('have table "Lovely table"')
|
|
870
|
+
expect(have_table('Lovely table', visible: false).description).to eq('have table "Lovely table"') # rubocop:disable Capybara/VisibilityMatcher
|
|
820
871
|
end
|
|
821
872
|
|
|
822
|
-
it
|
|
873
|
+
it 'passes if there is such a table' do
|
|
823
874
|
expect(html).to have_table('Lovely table')
|
|
824
875
|
end
|
|
825
876
|
|
|
826
|
-
it
|
|
877
|
+
it 'fails if there is no such table' do
|
|
827
878
|
expect do
|
|
828
879
|
expect(html).to have_table('No such Table')
|
|
829
|
-
end.to raise_error(/expected to find
|
|
880
|
+
end.to raise_error(/expected to find table "No such Table"/)
|
|
830
881
|
end
|
|
831
882
|
|
|
832
|
-
it
|
|
883
|
+
it 'supports compounding' do
|
|
833
884
|
expect(html).to have_table('nope').or have_table('Lovely table')
|
|
834
|
-
end
|
|
885
|
+
end
|
|
835
886
|
end
|
|
836
887
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
@session = session
|
|
841
|
-
@session.visit('/with_js')
|
|
842
|
-
@el = @session.find(:css, '#reload-me')
|
|
843
|
-
end
|
|
844
|
-
|
|
845
|
-
context "#and" do
|
|
846
|
-
it "should run 'concurrently'" do
|
|
847
|
-
Capybara.using_wait_time(2) do
|
|
848
|
-
matcher = have_text('this is not there').and have_text('neither is this')
|
|
849
|
-
expect(Benchmark.realtime do
|
|
850
|
-
expect {
|
|
851
|
-
expect(@el).to matcher
|
|
852
|
-
}.to raise_error RSpec::Expectations::ExpectationNotMetError
|
|
853
|
-
end).to be_between(2,3)
|
|
854
|
-
end
|
|
855
|
-
end
|
|
888
|
+
context 'compounding timing' do
|
|
889
|
+
let(:session) { session }
|
|
890
|
+
let(:el) { session.find(:css, '#reload-me') }
|
|
856
891
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
892
|
+
before do
|
|
893
|
+
session.visit('/with_js')
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
describe '#and' do
|
|
897
|
+
it "should run 'concurrently'" do
|
|
898
|
+
session.using_wait_time(2) do
|
|
899
|
+
matcher = have_text('this is not there').and have_text('neither is this')
|
|
900
|
+
expect(Benchmark.realtime do
|
|
901
|
+
expect do
|
|
902
|
+
expect(el).to matcher
|
|
903
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
|
904
|
+
end).to be_between(2, 3)
|
|
866
905
|
end
|
|
906
|
+
end
|
|
867
907
|
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
end
|
|
908
|
+
it "should run 'concurrently' and retry" do
|
|
909
|
+
session.click_link('reload-link')
|
|
910
|
+
session.using_wait_time(2) do
|
|
911
|
+
expect(Benchmark.realtime do
|
|
912
|
+
expect do
|
|
913
|
+
expect(el).to have_text('waiting to be reloaded').and(have_text('has been reloaded'))
|
|
914
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError, /expected to find text "waiting to be reloaded" in "has been reloaded"/
|
|
915
|
+
end).to be_between(2, 3)
|
|
877
916
|
end
|
|
917
|
+
end
|
|
878
918
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
919
|
+
it 'should ignore :wait options' do
|
|
920
|
+
session.using_wait_time(2) do
|
|
921
|
+
matcher = have_text('this is not there', wait: 5).and have_text('neither is this', wait: 6)
|
|
922
|
+
expect(Benchmark.realtime do
|
|
923
|
+
expect do
|
|
924
|
+
expect(el).to matcher
|
|
925
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
|
926
|
+
end).to be_between(2, 3)
|
|
884
927
|
end
|
|
885
928
|
end
|
|
886
929
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
expect(
|
|
930
|
+
it 'should work on the session' do
|
|
931
|
+
session.using_wait_time(2) do
|
|
932
|
+
session.click_link('reload-link')
|
|
933
|
+
expect(session).to have_selector(:css, 'h1', text: 'FooBar').and have_text('has been reloaded')
|
|
891
934
|
end
|
|
892
935
|
end
|
|
936
|
+
end
|
|
893
937
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
938
|
+
describe '#and_then' do
|
|
939
|
+
it 'should run sequentially' do
|
|
940
|
+
session.click_link('reload-link')
|
|
941
|
+
expect(el).to have_text('waiting to be reloaded').and_then have_text('has been reloaded')
|
|
942
|
+
end
|
|
943
|
+
end
|
|
944
|
+
|
|
945
|
+
describe '#or' do
|
|
946
|
+
it "should run 'concurrently'" do
|
|
947
|
+
session.using_wait_time(3) do
|
|
948
|
+
expect(Benchmark.realtime do
|
|
949
|
+
expect(el).to have_text('has been reloaded').or have_text('waiting to be reloaded')
|
|
950
|
+
end).to be < 1
|
|
901
951
|
end
|
|
952
|
+
end
|
|
902
953
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
end
|
|
954
|
+
it 'should retry' do
|
|
955
|
+
session.using_wait_time(3) do
|
|
956
|
+
expect(Benchmark.realtime do
|
|
957
|
+
expect do
|
|
958
|
+
expect(el).to have_text('has been reloaded').or have_text('random stuff')
|
|
959
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
|
960
|
+
end).to be > 3
|
|
911
961
|
end
|
|
962
|
+
end
|
|
912
963
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
end
|
|
964
|
+
it 'should ignore :wait options' do
|
|
965
|
+
session.using_wait_time(2) do
|
|
966
|
+
expect(Benchmark.realtime do
|
|
967
|
+
expect do
|
|
968
|
+
expect(el).to have_text('this is not there', wait: 10).or have_text('neither is this', wait: 15)
|
|
969
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
|
970
|
+
end).to be_between(2, 3)
|
|
921
971
|
end
|
|
972
|
+
end
|
|
922
973
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
end
|
|
974
|
+
it 'should work on the session' do
|
|
975
|
+
session.using_wait_time(2) do
|
|
976
|
+
session.click_link('reload-link')
|
|
977
|
+
expect(session).to have_selector(:css, 'h1', text: 'Not on the page').or have_text('has been reloaded')
|
|
928
978
|
end
|
|
929
979
|
end
|
|
930
980
|
end
|
|
931
981
|
end
|
|
932
982
|
end
|
|
983
|
+
# rubocop:enable RSpec/ExpectActual
|