capybara 3.21.0 → 3.22.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +14 -0
  4. data/README.md +13 -8
  5. data/lib/capybara.rb +38 -32
  6. data/lib/capybara/driver/node.rb +2 -2
  7. data/lib/capybara/minitest.rb +14 -1
  8. data/lib/capybara/minitest/spec.rb +20 -7
  9. data/lib/capybara/node/finders.rb +41 -47
  10. data/lib/capybara/node/matchers.rb +161 -72
  11. data/lib/capybara/queries/ancestor_query.rb +9 -7
  12. data/lib/capybara/queries/sibling_query.rb +11 -4
  13. data/lib/capybara/result.rb +2 -0
  14. data/lib/capybara/rspec/matchers.rb +16 -1
  15. data/lib/capybara/rspec/matchers/have_ancestor.rb +30 -0
  16. data/lib/capybara/rspec/matchers/have_sibling.rb +30 -0
  17. data/lib/capybara/selector.rb +153 -171
  18. data/lib/capybara/selector/definition/checkbox.rb +8 -5
  19. data/lib/capybara/selector/definition/radio_button.rb +8 -5
  20. data/lib/capybara/selector/filter_set.rb +4 -2
  21. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +35 -1
  22. data/lib/capybara/session.rb +74 -71
  23. data/lib/capybara/session/config.rb +1 -1
  24. data/lib/capybara/spec/session/check_spec.rb +6 -0
  25. data/lib/capybara/spec/session/choose_spec.rb +6 -0
  26. data/lib/capybara/spec/session/has_ancestor_spec.rb +44 -0
  27. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  28. data/lib/capybara/spec/session/select_spec.rb +5 -5
  29. data/lib/capybara/spec/views/form.erb +1 -1
  30. data/lib/capybara/version.rb +1 -1
  31. data/lib/capybara/window.rb +10 -10
  32. data/spec/minitest_spec.rb +11 -1
  33. data/spec/minitest_spec_spec.rb +11 -1
  34. data/spec/regexp_dissassembler_spec.rb +1 -1
  35. metadata +7 -2
@@ -10,14 +10,17 @@ Capybara.add_selector(:checkbox, locator_type: [String, Symbol]) do
10
10
 
11
11
  filter_set(:_field, %i[checked unchecked disabled name])
12
12
 
13
- node_filter(:option) do |node, value|
13
+ node_filter(%i[option with]) do |node, value|
14
14
  val = node.value
15
- (val == value.to_s).tap do |res|
16
- add_error("Expected option value to be #{value.inspect} but it was #{val.inspect}") unless res
15
+ (value.is_a?(Regexp) ? value.match?(val) : val == value.to_s).tap do |res|
16
+ add_error("Expected value to be #{value.inspect} but it was #{val.inspect}") unless res
17
17
  end
18
18
  end
19
19
 
20
- describe_node_filters do |option: nil, **|
21
- " with value #{option.inspect}" if option
20
+ describe_node_filters do |option: nil, with: nil, **|
21
+ desc = +''
22
+ desc << " with value #{option.inspect}" if option
23
+ desc << " with value #{with.inspec}" if with
24
+ desc
22
25
  end
23
26
  end
@@ -11,14 +11,17 @@ Capybara.add_selector(:radio_button, locator_type: [String, Symbol]) do
11
11
 
12
12
  filter_set(:_field, %i[checked unchecked disabled name])
13
13
 
14
- node_filter(:option) do |node, value|
14
+ node_filter(%i[option with]) do |node, value|
15
15
  val = node.value
16
- (val == value.to_s).tap do |res|
17
- add_error("Expected option value to be #{value.inspect} but it was #{val.inspect}") unless res
16
+ (value.is_a?(Regexp) ? value.match?(val) : val == value.to_s).tap do |res|
17
+ add_error("Expected value to be #{value.inspect} but it was #{val.inspect}") unless res
18
18
  end
19
19
  end
20
20
 
21
- describe_node_filters do |option: nil, **|
22
- " with value #{option.inspect}" if option
21
+ describe_node_filters do |option: nil, with: nil, **|
22
+ desc = +''
23
+ desc << " with value #{option.inspect}" if option
24
+ desc << " with value #{with.inspec}" if with
25
+ desc
23
26
  end
24
27
  end
@@ -15,8 +15,10 @@ module Capybara
15
15
  instance_eval(&block)
16
16
  end
17
17
 
18
- def node_filter(name, *types_and_options, &block)
19
- add_filter(name, Filters::NodeFilter, *types_and_options, &block)
18
+ def node_filter(names, *types_and_options, &block)
19
+ Array(names).each do |name|
20
+ add_filter(name, Filters::NodeFilter, *types_and_options, &block)
21
+ end
20
22
  end
21
23
  alias_method :filter, :node_filter
22
24
 
@@ -33,11 +33,38 @@ module Capybara::Selenium::Driver::ChromeDriver
33
33
 
34
34
  switch_to_window(window_handles.first)
35
35
  window_handles.slice(1..-1).each { |win| close_window(win) }
36
- super
36
+ return super if chromedriver_version < 73
37
+
38
+ timer = Capybara::Helpers.timer(expire_in: 10)
39
+ begin
40
+ @browser.navigate.to('about:blank')
41
+ clear_storage unless uniform_storage_clear?
42
+ wait_for_empty_page(timer)
43
+ rescue *unhandled_alert_errors
44
+ accept_unhandled_reset_alert
45
+ retry
46
+ end
47
+
48
+ execute_cdp('Storage.clearDataForOrigin', origin: '*', storageTypes: storage_types_to_clear)
37
49
  end
38
50
 
39
51
  private
40
52
 
53
+ def storage_types_to_clear
54
+ types = ['cookies']
55
+ types << 'local_storage' if clear_all_storage?
56
+ types.join(',')
57
+ end
58
+
59
+ def clear_all_storage?
60
+ options.values_at(:clear_session_storage, :clear_local_storage).none? { |s| s == false }
61
+ end
62
+
63
+ def uniform_storage_clear?
64
+ clear = options.values_at(:clear_session_storage, :clear_local_storage)
65
+ clear.all? { |s| s == false } || clear.none? { |s| s == false }
66
+ end
67
+
41
68
  def clear_storage
42
69
  # Chrome errors if attempt to clear storage on about:blank
43
70
  # In W3C mode it crashes chromedriver
@@ -69,6 +96,13 @@ private
69
96
  def bridge
70
97
  browser.send(:bridge)
71
98
  end
99
+
100
+ def chromedriver_version
101
+ @chromedriver_version ||= begin
102
+ caps = browser.capabilities
103
+ caps['chrome']&.fetch('chromedriverVersion', nil).to_f
104
+ end
105
+ end
72
106
  end
73
107
 
74
108
  Capybara::Selenium::Driver.register_specialization :chrome, Capybara::Selenium::Driver::ChromeDriver
@@ -6,7 +6,7 @@ require 'addressable/uri'
6
6
  module Capybara
7
7
  ##
8
8
  #
9
- # The Session class represents a single user's interaction with the system. The Session can use
9
+ # The {Session} class represents a single user's interaction with the system. The {Session} can use
10
10
  # any of the underlying drivers. A session can be initialized manually like this:
11
11
  #
12
12
  # session = Capybara::Session.new(:culerity, MyRackApp)
@@ -17,23 +17,23 @@ module Capybara
17
17
  # session = Capybara::Session.new(:culerity)
18
18
  # session.visit('http://www.google.com')
19
19
  #
20
- # When Capybara.threadsafe == true the sessions options will be initially set to the
20
+ # When {Capybara.configure threadsafe} is `true` the sessions options will be initially set to the
21
21
  # current values of the global options and a configuration block can be passed to the session initializer.
22
- # For available options see {Capybara::SessionConfig::OPTIONS}
22
+ # For available options see {Capybara::SessionConfig::OPTIONS}:
23
23
  #
24
24
  # session = Capybara::Session.new(:driver, MyRackApp) do |config|
25
25
  # config.app_host = "http://my_host.dev"
26
26
  # end
27
27
  #
28
- # Session provides a number of methods for controlling the navigation of the page, such as +visit+,
29
- # +current_path, and so on. It also delegates a number of methods to a Capybara::Document, representing
28
+ # The {Session} provides a number of methods for controlling the navigation of the page, such as {#visit},
29
+ # {#current_path}, and so on. It also delegates a number of methods to a {Capybara::Document}, representing
30
30
  # the current HTML document. This allows interaction:
31
31
  #
32
32
  # session.fill_in('q', with: 'Capybara')
33
33
  # session.click_button('Search')
34
34
  # expect(session).to have_content('Capybara')
35
35
  #
36
- # When using capybara/dsl, the Session is initialized automatically for you.
36
+ # When using `capybara/dsl`, the {Session} is initialized automatically for you.
37
37
  #
38
38
  class Session
39
39
  include Capybara::SessionMatchers
@@ -107,21 +107,21 @@ module Capybara
107
107
 
108
108
  ##
109
109
  #
110
- # Reset the session (i.e. remove cookies and navigate to blank page)
110
+ # Reset the session (i.e. remove cookies and navigate to blank page).
111
111
  #
112
112
  # This method does not:
113
113
  #
114
- # * accept modal dialogs if they are present (Selenium driver now does, others may not)
115
- # * clear browser cache/HTML 5 local storage/IndexedDB/Web SQL database/etc.
116
- # * modify state of the driver/underlying browser in any other way
114
+ # * accept modal dialogs if they are present (Selenium driver now does, others may not)
115
+ # * clear browser cache/HTML 5 local storage/IndexedDB/Web SQL database/etc.
116
+ # * modify state of the driver/underlying browser in any other way
117
117
  #
118
118
  # as doing so will result in performance downsides and it's not needed to do everything from the list above for most apps.
119
119
  #
120
120
  # If you want to do anything from the list above on a general basis you can:
121
121
  #
122
- # * write RSpec/Cucumber/etc. after hook
123
- # * monkeypatch this method
124
- # * use Ruby's `prepend` method
122
+ # * write RSpec/Cucumber/etc. after hook
123
+ # * monkeypatch this method
124
+ # * use Ruby's `prepend` method
125
125
  #
126
126
  def reset!
127
127
  if @touched
@@ -136,8 +136,7 @@ module Capybara
136
136
 
137
137
  ##
138
138
  #
139
- # Disconnect from the current driver. A new driver will be instantiated on the next interaction
140
- #
139
+ # Disconnect from the current driver. A new driver will be instantiated on the next interaction.
141
140
  #
142
141
  def quit
143
142
  @driver.quit if @driver.respond_to? :quit
@@ -148,7 +147,7 @@ module Capybara
148
147
 
149
148
  ##
150
149
  #
151
- # Raise errors encountered in the server
150
+ # Raise errors encountered in the server.
152
151
  #
153
152
  def raise_server_error!
154
153
  return unless @server&.error
@@ -168,9 +167,9 @@ module Capybara
168
167
 
169
168
  ##
170
169
  #
171
- # Returns a hash of response headers. Not supported by all drivers (e.g. Selenium)
170
+ # Returns a hash of response headers. Not supported by all drivers (e.g. Selenium).
172
171
  #
173
- # @return [Hash{String => String}] A hash of response headers.
172
+ # @return [Hash<String, String>] A hash of response headers.
174
173
  #
175
174
  def response_headers
176
175
  driver.response_headers
@@ -178,7 +177,7 @@ module Capybara
178
177
 
179
178
  ##
180
179
  #
181
- # Returns the current HTTP status code as an Integer. Not supported by all drivers (e.g. Selenium)
180
+ # Returns the current HTTP status code as an integer. Not supported by all drivers (e.g. Selenium).
182
181
  #
183
182
  # @return [Integer] Current HTTP status code
184
183
  #
@@ -238,13 +237,13 @@ module Capybara
238
237
  #
239
238
  # For drivers which can run against an external application, such as the selenium driver
240
239
  # giving an absolute URL will navigate to that page. This allows testing applications
241
- # running on remote servers. For these drivers, setting {Capybara.app_host} will make the
240
+ # running on remote servers. For these drivers, setting {Capybara.configure app_host} will make the
242
241
  # remote server the default. For example:
243
242
  #
244
243
  # Capybara.app_host = 'http://google.com'
245
244
  # session.visit('/') # visits the google homepage
246
245
  #
247
- # If {Capybara.always_include_port} is set to true and this session is running against
246
+ # If {Capybara.configure always_include_port} is set to `true` and this session is running against
248
247
  # a rack application, then the port that the rack application is running on will automatically
249
248
  # be inserted into the URL. Supposing the app is running on port `4567`, doing something like:
250
249
  #
@@ -279,7 +278,7 @@ module Capybara
279
278
 
280
279
  ##
281
280
  #
282
- # Refresh the page
281
+ # Refresh the page.
283
282
  #
284
283
  def refresh
285
284
  raise_server_error!
@@ -304,8 +303,8 @@ module Capybara
304
303
 
305
304
  ##
306
305
  #
307
- # Executes the given block within the context of a node. `within` takes the
308
- # same options as `find`, as well as a block. For the duration of the
306
+ # Executes the given block within the context of a node. {#within} takes the
307
+ # same options as {Capybara::Node::Finders#find #find}, as well as a block. For the duration of the
309
308
  # block, any command to Capybara will be handled as though it were scoped
310
309
  # to the given element.
311
310
  #
@@ -313,18 +312,18 @@ module Capybara
313
312
  # fill_in('Street', with: '12 Main Street')
314
313
  # end
315
314
  #
316
- # Just as with `find`, if multiple elements match the selector given to
317
- # `within`, an error will be raised, and just as with `find`, this
315
+ # Just as with `#find`, if multiple elements match the selector given to
316
+ # {#within}, an error will be raised, and just as with `#find`, this
318
317
  # behaviour can be controlled through the `:match` and `:exact` options.
319
318
  #
320
319
  # It is possible to omit the first parameter, in that case, the selector is
321
- # assumed to be of the type set in Capybara.default_selector.
320
+ # assumed to be of the type set in {Capybara.configure default_selector}.
322
321
  #
323
322
  # within('div#delivery-address') do
324
323
  # fill_in('Street', with: '12 Main Street')
325
324
  # end
326
325
  #
327
- # Note that a lot of uses of `within` can be replaced more succinctly with
326
+ # Note that a lot of uses of {#within} can be replaced more succinctly with
328
327
  # chaining:
329
328
  #
330
329
  # find('div#delivery-address').fill_in('Street', with: '12 Main Street')
@@ -370,18 +369,18 @@ module Capybara
370
369
 
371
370
  ##
372
371
  #
373
- # Switch to the given frame
372
+ # Switch to the given frame.
374
373
  #
375
374
  # If you use this method you are responsible for making sure you switch back to the parent frame when done in the frame changed to.
376
- # Capybara::Session#within_frame is preferred over this method and should be used when possible.
375
+ # {#within_frame} is preferred over this method and should be used when possible.
377
376
  # May not be supported by all drivers.
378
377
  #
379
378
  # @overload switch_to_frame(element)
380
- # @param [Capybara::Node::Element] iframe/frame element to switch to
381
- # @overload switch_to_frame(:parent)
382
- # Switch to the parent frame
383
- # @overload switch_to_frame(:top)
384
- # Switch to the top level document
379
+ # @param [Capybara::Node::Element] element iframe/frame element to switch to
380
+ # @overload switch_to_frame(location)
381
+ # @param [Symbol] location relative location of the frame to switch to
382
+ # * :parent - the parent frame
383
+ # * :top - the top level document
385
384
  #
386
385
  def switch_to_frame(frame)
387
386
  case frame
@@ -452,8 +451,8 @@ module Capybara
452
451
  end
453
452
 
454
453
  ##
455
- # Open new window.
456
- # Current window doesn't change as the result of this call.
454
+ # Open a new window.
455
+ # The current window doesn't change as the result of this call.
457
456
  # It should be switched to explicitly.
458
457
  #
459
458
  # @return [Capybara::Window] window that has been opened
@@ -469,9 +468,11 @@ module Capybara
469
468
  end
470
469
 
471
470
  ##
471
+ # Switch to the given window.
472
+ #
472
473
  # @overload switch_to_window(&block)
473
474
  # Switches to the first window for which given block returns a value other than false or nil.
474
- # If window that matches block can't be found, the window will be switched back and `WindowError` will be raised.
475
+ # If window that matches block can't be found, the window will be switched back and {Capybara::WindowError} will be raised.
475
476
  # @example
476
477
  # window = switch_to_window { title == 'Page title' }
477
478
  # @raise [Capybara::WindowError] if no window matches given block
@@ -480,8 +481,8 @@ module Capybara
480
481
  # @raise [Capybara::Driver::Base#no_such_window_error] if nonexistent (e.g. closed) window was passed
481
482
  #
482
483
  # @return [Capybara::Window] window that has been switched to
483
- # @raise [Capybara::ScopeError] if this method is invoked inside `within` or
484
- # `within_frame` methods
484
+ # @raise [Capybara::ScopeError] if this method is invoked inside {#within} or
485
+ # {#within_frame} methods
485
486
  # @raise [ArgumentError] if both or neither arguments were provided
486
487
  #
487
488
  def switch_to_window(window = nil, **options, &window_locator)
@@ -501,20 +502,20 @@ module Capybara
501
502
  #
502
503
  # 1. Switches to the given window (it can be located by window instance/lambda/string).
503
504
  # 2. Executes the given block (within window located at previous step).
504
- # 3. Switches back (this step will be invoked even if exception will happen at second step)
505
+ # 3. Switches back (this step will be invoked even if an exception occurs at the second step).
505
506
  #
506
507
  # @overload within_window(window) { do_something }
507
- # @param window [Capybara::Window] instance of `Capybara::Window` class
508
+ # @param window [Capybara::Window] instance of {Capybara::Window} class
508
509
  # that will be switched to
509
510
  # @raise [driver#no_such_window_error] if nonexistent (e.g. closed) window was passed
510
511
  # @overload within_window(proc_or_lambda) { do_something }
511
- # @param lambda [Proc] lambda. First window for which lambda
512
+ # @param lambda [Proc] First window for which lambda
512
513
  # returns a value other than false or nil will be switched to.
513
514
  # @example
514
515
  # within_window(->{ page.title == 'Page title' }) { click_button 'Submit' }
515
516
  # @raise [Capybara::WindowError] if no window matching lambda was found
516
517
  #
517
- # @raise [Capybara::ScopeError] if this method is invoked inside `within_frame` method
518
+ # @raise [Capybara::ScopeError] if this method is invoked inside {#within_frame} method
518
519
  # @return value returned by the block
519
520
  #
520
521
  def within_window(window_or_proc)
@@ -544,11 +545,11 @@ module Capybara
544
545
  # Get the window that has been opened by the passed block.
545
546
  # It will wait for it to be opened (in the same way as other Capybara methods wait).
546
547
  # It's better to use this method than `windows.last`
547
- # {https://dvcs.w3.org/hg/webdriver/raw-file/default/webdriver-spec.html#h_note_10 as order of windows isn't defined in some drivers}
548
+ # {https://dvcs.w3.org/hg/webdriver/raw-file/default/webdriver-spec.html#h_note_10 as order of windows isn't defined in some drivers}.
548
549
  #
549
550
  # @overload window_opened_by(**options, &block)
550
551
  # @param options [Hash]
551
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) maximum wait time
552
+ # @option options [Numeric] :wait maximum wait time. Defaults to {Capybara.configure default_max_wait_time}
552
553
  # @return [Capybara::Window] the window that has been opened within a block
553
554
  # @raise [Capybara::WindowError] if block passed to window hasn't opened window
554
555
  # or opened more than one window
@@ -570,11 +571,11 @@ module Capybara
570
571
  ##
571
572
  #
572
573
  # Execute the given script, not returning a result. This is useful for scripts that return
573
- # complex objects, such as jQuery statements. +execute_script+ should be used over
574
- # +evaluate_script+ whenever possible.
574
+ # complex objects, such as jQuery statements. {#execute_script} should be used over
575
+ # {#evaluate_script} whenever possible.
575
576
  #
576
577
  # @param [String] script A string of JavaScript to execute
577
- # @param args Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers
578
+ # @param args Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers
578
579
  #
579
580
  def execute_script(script, *args)
580
581
  @touched = true
@@ -584,10 +585,11 @@ module Capybara
584
585
  ##
585
586
  #
586
587
  # Evaluate the given JavaScript and return the result. Be careful when using this with
587
- # scripts that return complex objects, such as jQuery statements. +execute_script+ might
588
+ # scripts that return complex objects, such as jQuery statements. {#execute_script} might
588
589
  # be a better alternative.
589
590
  #
590
591
  # @param [String] script A string of JavaScript to evaluate
592
+ # @param args Optional arguments that will be passed to the script
591
593
  # @return [Object] The result of the evaluated JavaScript (may be driver specific)
592
594
  #
593
595
  def evaluate_script(script, *args)
@@ -601,6 +603,7 @@ module Capybara
601
603
  # Evaluate the given JavaScript and obtain the result from a callback function which will be passed as the last argument to the script.
602
604
  #
603
605
  # @param [String] script A string of JavaScript to evaluate
606
+ # @param args Optional arguments that will be passed to the script
604
607
  # @return [Object] The result of the evaluated JavaScript (may be driver specific)
605
608
  #
606
609
  def evaluate_async_script(script, *args)
@@ -614,17 +617,17 @@ module Capybara
614
617
  # Execute the block, accepting a alert.
615
618
  #
616
619
  # @!macro modal_params
617
- # Expects a block whose actions will trigger the display modal to appear
620
+ # Expects a block whose actions will trigger the display modal to appear.
618
621
  # @example
619
622
  # $0 do
620
623
  # click_link('link that triggers appearance of system modal')
621
624
  # end
622
625
  # @overload $0(text, **options, &blk)
623
- # @param text [String, Regexp] Text or regex to match against the text in the modal. If not provided any modal is matched
624
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time to wait for the modal to appear after executing the block.
626
+ # @param text [String, Regexp] Text or regex to match against the text in the modal. If not provided any modal is matched.
627
+ # @option options [Numeric] :wait Maximum time to wait for the modal to appear after executing the block. Defaults to {Capybara.configure default_max_wait_time}.
625
628
  # @yield Block whose actions will trigger the system modal
626
629
  # @overload $0(**options, &blk)
627
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time to wait for the modal to appear after executing the block.
630
+ # @option options [Numeric] :wait Maximum time to wait for the modal to appear after executing the block. Defaults to {Capybara.configure default_max_wait_time}.
628
631
  # @yield Block whose actions will trigger the system modal
629
632
  # @return [String] the message shown in the modal
630
633
  # @raise [Capybara::ModalNotFound] if modal dialog hasn't been found
@@ -676,12 +679,12 @@ module Capybara
676
679
 
677
680
  ##
678
681
  #
679
- # Save a snapshot of the page. If `Capybara.asset_host` is set it will inject `base` tag
680
- # pointing to `asset_host`.
682
+ # Save a snapshot of the page. If {Capybara.configure asset_host} is set it will inject `base` tag
683
+ # pointing to {Capybara.configure asset_host}.
681
684
  #
682
- # If invoked without arguments it will save file to `Capybara.save_path`
683
- # and file will be given randomly generated filename. If invoked with a relative path
684
- # the path will be relative to `Capybara.save_path`
685
+ # If invoked without arguments it will save file to {Capybara.configure save_path}
686
+ # and file will be given randomly generated filename. If invoked with a relative path
687
+ # the path will be relative to {Capybara.configure save_path}.
685
688
  #
686
689
  # @param [String] path the path to where it should be saved
687
690
  # @return [String] the path to which the file was saved
@@ -696,9 +699,9 @@ module Capybara
696
699
  #
697
700
  # Save a snapshot of the page and open it in a browser for inspection.
698
701
  #
699
- # If invoked without arguments it will save file to `Capybara.save_path`
700
- # and file will be given randomly generated filename. If invoked with a relative path
701
- # the path will be relative to `Capybara.save_path`
702
+ # If invoked without arguments it will save file to {Capybara.configure save_path}
703
+ # and file will be given randomly generated filename. If invoked with a relative path
704
+ # the path will be relative to {Capybara.configure save_path}.
702
705
  #
703
706
  # @param [String] path the path to where it should be saved
704
707
  #
@@ -710,9 +713,9 @@ module Capybara
710
713
  #
711
714
  # Save a screenshot of page.
712
715
  #
713
- # If invoked without arguments it will save file to `Capybara.save_path`
714
- # and file will be given randomly generated filename. If invoked with a relative path
715
- # the path will be relative to `Capybara.save_path`
716
+ # If invoked without arguments it will save file to {Capybara.configure save_path}
717
+ # and file will be given randomly generated filename. If invoked with a relative path
718
+ # the path will be relative to {Capybara.configure save_path}.
716
719
  #
717
720
  # @param [String] path the path to where it should be saved
718
721
  # @param [Hash] options a customizable set of options
@@ -725,9 +728,9 @@ module Capybara
725
728
  #
726
729
  # Save a screenshot of the page and open it for inspection.
727
730
  #
728
- # If invoked without arguments it will save file to `Capybara.save_path`
729
- # and file will be given randomly generated filename. If invoked with a relative path
730
- # the path will be relative to `Capybara.save_path`
731
+ # If invoked without arguments it will save file to {Capybara.configure save_path}
732
+ # and file will be given randomly generated filename. If invoked with a relative path
733
+ # the path will be relative to {Capybara.configure save_path}.
731
734
  #
732
735
  # @param [String] path the path to where it should be saved
733
736
  # @param [Hash] options a customizable set of options
@@ -766,7 +769,7 @@ module Capybara
766
769
 
767
770
  ##
768
771
  #
769
- # Yield a block using a specific wait time
772
+ # Yield a block using a specific maximum wait time.
770
773
  #
771
774
  def using_wait_time(seconds)
772
775
  if Capybara.threadsafe
@@ -784,8 +787,8 @@ module Capybara
784
787
 
785
788
  ##
786
789
  #
787
- # Accepts a block to set the configuration options if Capybara.threadsafe == true. Note that some options only have an effect
788
- # if set at initialization time, so look at the configuration block that can be passed to the initializer too
790
+ # Accepts a block to set the configuration options if {Capybara.configure threadsafe} is `true`. Note that some options only have an effect
791
+ # if set at initialization time, so look at the configuration block that can be passed to the initializer too.
789
792
  #
790
793
  def configure
791
794
  raise 'Session configuration is only supported when Capybara.threadsafe == true' unless Capybara.threadsafe