capybara 3.3.1 → 3.4.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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +16 -0
  3. data/README.md +5 -7
  4. data/lib/capybara.rb +7 -6
  5. data/lib/capybara/config.rb +1 -1
  6. data/lib/capybara/dsl.rb +2 -2
  7. data/lib/capybara/helpers.rb +3 -3
  8. data/lib/capybara/minitest/spec.rb +3 -3
  9. data/lib/capybara/node/actions.rb +18 -18
  10. data/lib/capybara/node/base.rb +1 -1
  11. data/lib/capybara/node/element.rb +2 -2
  12. data/lib/capybara/node/finders.rb +6 -6
  13. data/lib/capybara/node/matchers.rb +5 -5
  14. data/lib/capybara/node/simple.rb +2 -2
  15. data/lib/capybara/queries/ancestor_query.rb +1 -1
  16. data/lib/capybara/queries/base_query.rb +12 -11
  17. data/lib/capybara/queries/current_path_query.rb +1 -1
  18. data/lib/capybara/queries/selector_query.rb +39 -15
  19. data/lib/capybara/queries/sibling_query.rb +1 -1
  20. data/lib/capybara/queries/text_query.rb +1 -1
  21. data/lib/capybara/rack_test/browser.rb +7 -7
  22. data/lib/capybara/rack_test/driver.rb +1 -1
  23. data/lib/capybara/rack_test/form.rb +7 -7
  24. data/lib/capybara/rack_test/node.rb +16 -16
  25. data/lib/capybara/rails.rb +1 -1
  26. data/lib/capybara/result.rb +8 -4
  27. data/lib/capybara/rspec/features.rb +4 -4
  28. data/lib/capybara/rspec/matchers.rb +6 -6
  29. data/lib/capybara/selector.rb +106 -90
  30. data/lib/capybara/selector/css.rb +4 -4
  31. data/lib/capybara/selector/filter_set.rb +52 -8
  32. data/lib/capybara/selector/selector.rb +39 -15
  33. data/lib/capybara/selenium/driver.rb +10 -10
  34. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +8 -0
  35. data/lib/capybara/selenium/node.rb +9 -10
  36. data/lib/capybara/selenium/nodes/chrome_node.rb +18 -0
  37. data/lib/capybara/selenium/nodes/marionette_node.rb +32 -7
  38. data/lib/capybara/server.rb +3 -3
  39. data/lib/capybara/server/animation_disabler.rb +1 -1
  40. data/lib/capybara/server/middleware.rb +1 -1
  41. data/lib/capybara/session.rb +23 -19
  42. data/lib/capybara/session/config.rb +18 -3
  43. data/lib/capybara/spec/public/test.js +1 -1
  44. data/lib/capybara/spec/session/accept_alert_spec.rb +10 -10
  45. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  46. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  47. data/lib/capybara/spec/session/all_spec.rb +33 -32
  48. data/lib/capybara/spec/session/ancestor_spec.rb +19 -19
  49. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +38 -38
  50. data/lib/capybara/spec/session/assert_current_path_spec.rb +16 -16
  51. data/lib/capybara/spec/session/assert_selector_spec.rb +53 -53
  52. data/lib/capybara/spec/session/assert_style_spec.rb +3 -3
  53. data/lib/capybara/spec/session/assert_text_spec.rb +31 -30
  54. data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
  55. data/lib/capybara/spec/session/attach_file_spec.rb +51 -52
  56. data/lib/capybara/spec/session/body_spec.rb +6 -6
  57. data/lib/capybara/spec/session/check_spec.rb +52 -47
  58. data/lib/capybara/spec/session/choose_spec.rb +32 -32
  59. data/lib/capybara/spec/session/click_button_spec.rb +103 -103
  60. data/lib/capybara/spec/session/click_link_or_button_spec.rb +24 -23
  61. data/lib/capybara/spec/session/click_link_spec.rb +49 -48
  62. data/lib/capybara/spec/session/current_scope_spec.rb +7 -7
  63. data/lib/capybara/spec/session/current_url_spec.rb +26 -27
  64. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  65. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  66. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
  67. data/lib/capybara/spec/session/element/match_css_spec.rb +10 -10
  68. data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
  69. data/lib/capybara/spec/session/element/matches_selector_spec.rb +51 -51
  70. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  71. data/lib/capybara/spec/session/evaluate_script_spec.rb +15 -8
  72. data/lib/capybara/spec/session/execute_script_spec.rb +7 -7
  73. data/lib/capybara/spec/session/fill_in_spec.rb +43 -42
  74. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  75. data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
  76. data/lib/capybara/spec/session/find_field_spec.rb +32 -30
  77. data/lib/capybara/spec/session/find_link_spec.rb +21 -21
  78. data/lib/capybara/spec/session/find_spec.rb +153 -135
  79. data/lib/capybara/spec/session/first_spec.rb +41 -41
  80. data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
  81. data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
  82. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +17 -17
  83. data/lib/capybara/spec/session/frame/within_frame_spec.rb +31 -17
  84. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  85. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  86. data/lib/capybara/spec/session/has_all_selectors_spec.rb +17 -17
  87. data/lib/capybara/spec/session/has_button_spec.rb +13 -13
  88. data/lib/capybara/spec/session/has_css_spec.rb +133 -131
  89. data/lib/capybara/spec/session/has_current_path_spec.rb +29 -29
  90. data/lib/capybara/spec/session/has_field_spec.rb +58 -58
  91. data/lib/capybara/spec/session/has_link_spec.rb +4 -4
  92. data/lib/capybara/spec/session/has_none_selectors_spec.rb +24 -24
  93. data/lib/capybara/spec/session/has_select_spec.rb +43 -43
  94. data/lib/capybara/spec/session/has_selector_spec.rb +71 -71
  95. data/lib/capybara/spec/session/has_style_spec.rb +3 -3
  96. data/lib/capybara/spec/session/has_table_spec.rb +4 -4
  97. data/lib/capybara/spec/session/has_text_spec.rb +53 -52
  98. data/lib/capybara/spec/session/has_title_spec.rb +14 -14
  99. data/lib/capybara/spec/session/has_xpath_spec.rb +39 -38
  100. data/lib/capybara/spec/session/headers_spec.rb +1 -1
  101. data/lib/capybara/spec/session/html_spec.rb +6 -6
  102. data/lib/capybara/spec/session/node_spec.rb +129 -123
  103. data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
  104. data/lib/capybara/spec/session/refresh_spec.rb +4 -7
  105. data/lib/capybara/spec/session/reset_session_spec.rb +28 -28
  106. data/lib/capybara/spec/session/response_code_spec.rb +1 -1
  107. data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
  108. data/lib/capybara/spec/session/save_page_spec.rb +37 -37
  109. data/lib/capybara/spec/session/save_screenshot_spec.rb +6 -6
  110. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  111. data/lib/capybara/spec/session/select_spec.rb +81 -81
  112. data/lib/capybara/spec/session/selectors_spec.rb +17 -17
  113. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  114. data/lib/capybara/spec/session/text_spec.rb +23 -23
  115. data/lib/capybara/spec/session/title_spec.rb +5 -5
  116. data/lib/capybara/spec/session/uncheck_spec.rb +24 -20
  117. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  118. data/lib/capybara/spec/session/visit_spec.rb +48 -49
  119. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
  120. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -16
  121. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -2
  122. data/lib/capybara/spec/session/window/window_spec.rb +4 -4
  123. data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
  124. data/lib/capybara/spec/session/within_spec.rb +41 -41
  125. data/lib/capybara/spec/spec_helper.rb +11 -9
  126. data/lib/capybara/spec/test_app.rb +18 -17
  127. data/lib/capybara/spec/views/form.erb +29 -31
  128. data/lib/capybara/spec/views/with_html.erb +2 -2
  129. data/lib/capybara/version.rb +1 -1
  130. data/spec/basic_node_spec.rb +23 -23
  131. data/spec/capybara_spec.rb +20 -20
  132. data/spec/css_splitter_spec.rb +7 -7
  133. data/spec/dsl_spec.rb +37 -32
  134. data/spec/filter_set_spec.rb +4 -4
  135. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  136. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  137. data/spec/minitest_spec.rb +4 -4
  138. data/spec/minitest_spec_spec.rb +23 -23
  139. data/spec/per_session_config_spec.rb +5 -5
  140. data/spec/rack_test_spec.rb +44 -44
  141. data/spec/result_spec.rb +14 -14
  142. data/spec/rspec/features_spec.rb +13 -13
  143. data/spec/rspec/scenarios_spec.rb +4 -4
  144. data/spec/rspec/shared_spec_matchers.rb +282 -281
  145. data/spec/rspec/views_spec.rb +3 -3
  146. data/spec/rspec_matchers_spec.rb +10 -10
  147. data/spec/rspec_spec.rb +29 -29
  148. data/spec/selector_spec.rb +64 -64
  149. data/spec/selenium_spec_chrome.rb +14 -22
  150. data/spec/selenium_spec_chrome_remote.rb +28 -8
  151. data/spec/selenium_spec_edge.rb +9 -4
  152. data/spec/selenium_spec_firefox_remote.rb +87 -0
  153. data/spec/selenium_spec_ie.rb +9 -4
  154. data/spec/selenium_spec_marionette.rb +42 -18
  155. data/spec/server_spec.rb +29 -27
  156. data/spec/session_spec.rb +17 -17
  157. data/spec/shared_selenium_session.rb +70 -52
  158. data/spec/spec_helper.rb +1 -1
  159. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31eb0715167852439533fdb10e4cb15b9cb1d7531e7821a6f70d2a208d6cb232
4
- data.tar.gz: 58f5b7496bade61b732ab10831dc237f64dc7f288bd34bdbe61b58535d0fa475
3
+ metadata.gz: 354c57c570fb124607ab4255934f26bdb55b81716b846a2d76bb938ecae5d0c0
4
+ data.tar.gz: 128b9ee025bcd0021bc7e966a57d96fc05b516bd8dcb29756f3206f8aef15d4f
5
5
  SHA512:
6
- metadata.gz: 5563fda1e5f2965eb8d93cf42ecb8423bb316d6381410a79dc3a18d41364502b893ff5ce7974f48888f87583f53d7b43037a5f80c20fd20b1bad6a2d1a144f51
7
- data.tar.gz: 8361afb0ecb0fbe34b045b031ae2466483128f69ccb2be4637ad77a7ec41bac39fa44acd8ae1cbefdb94b4bec1679ee2e6e25fadc7d8062130ac59d992b45c36
6
+ metadata.gz: c55429aed39e48dbe84375f0822e2f0f244e4572474a797a27e8f83bdf0fa3c8062ca91d6696aba1b54c228908385351c483598a9f44718529d7ad4139b0717c
7
+ data.tar.gz: 8c61a46eb89183e28c4e0e7be76118ccecceb3383a6c7c37b2f9d7d0aa5efe5971146a97374146df09881a2fe0da94f58a89822cdb9e6d53b95f502782eb9106
data/History.md CHANGED
@@ -1,3 +1,19 @@
1
+ # Version 3.4.0
2
+ Release date: 2018-07-19
3
+
4
+ ### Fixed
5
+
6
+ * Make selenium driver :backspace clear stategy work even if caret location is in middle of field content [Champier Cyril]
7
+ * Selenium issue with fieldset nested in disabled fieldset not being considered disabled
8
+ * `Session#evaluate_script` and `Element#evaluate_script` now strip leading/trailing whitespace from scripts [Ian Lesperance]
9
+
10
+ ### Added
11
+
12
+ * Work around Selenium lack of support for `file_detector` with remote geckodriver
13
+ * `#within_frame` locator is optional when only one frame exists
14
+ * `Capybara.test_id` option that allows for matching the Capybara provided selector types on an arbitrary attribute
15
+ (defaults to nil), set to your test id attribute ('data-test-id, etc) if using test id attributes in your project
16
+
1
17
  # Version 3.3.1
2
18
  Release date: 2018-06-27
3
19
 
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
8
8
 
9
9
  **Note** You are viewing the README for the development version of Capybara. If you are using the current release version
10
- you can find the README at https://github.com/teamcapybara/capybara/blob/3.3_stable/README.md
10
+ you can find the README at https://github.com/teamcapybara/capybara/blob/3.4_stable/README.md
11
11
 
12
12
 
13
13
  Capybara helps you test web applications by simulating how a real user would
@@ -387,12 +387,10 @@ See the section on adding and configuring drivers.
387
387
 
388
388
  ### <a name="selenium"></a>Selenium
389
389
 
390
- At the moment, Capybara supports [Selenium 2.0+
391
- (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
392
- *not* Selenium RC. In order to use Selenium, you'll need to install the
393
- `selenium-webdriver` gem, and add it to your Gemfile if you're using bundler.
394
- Provided Firefox is installed, everything is set up for you, and you should be
395
- able to start using Selenium right away.
390
+ Capybara supports [Selenium 3.5+
391
+ (Webdriver)](https://www.seleniumhq.org/projects/webdriver/).
392
+ In order to use Selenium, you'll need to install the`selenium-webdriver` gem,
393
+ and add it to your Gemfile if you're using bundler.
396
394
 
397
395
  **Note**: drivers which run the server in a different thread may not share the
398
396
  same transaction as your tests, causing data not to be shared between your test
@@ -83,6 +83,7 @@ module Capybara
83
83
  # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
84
84
  # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
85
85
  # [default_set_options = Hash] The default options passed to Node::set (Default: {})
86
+ # [test_id = Symbol/String/nil] Optional attribute to match locator aginst with builtin selectors along with id (Default: nil)
86
87
  #
87
88
  # === DSL Options
88
89
  #
@@ -444,23 +445,22 @@ Capybara.register_server :puma do |app, port, host, **options|
444
445
  begin
445
446
  require 'rack/handler/puma'
446
447
  rescue LoadError
447
- raise LoadError, "Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`."
448
+ raise LoadError, 'Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`.'
448
449
  end
449
450
  # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
450
451
  # Therefore construct and run the Server instance ourselves.
451
452
  # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
452
453
 
453
- conf = Rack::Handler::Puma.config(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
454
+ conf = Rack::Handler::Puma.config(app, { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }.merge(options))
454
455
  events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
455
456
 
456
- events.log "Capybara starting Puma..."
457
+ events.log 'Capybara starting Puma...'
457
458
  events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
458
459
  events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
459
460
 
460
461
  Puma::Server.new(conf.app, events, conf.options).tap do |s|
461
462
  s.binder.parse conf.options[:binds], s.events
462
- s.min_threads = conf.options[:min_threads]
463
- s.max_threads = conf.options[:max_threads]
463
+ s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
464
464
  end.run.join
465
465
  end
466
466
 
@@ -471,7 +471,7 @@ Capybara.configure do |config|
471
471
  config.default_selector = :css
472
472
  config.default_max_wait_time = 2
473
473
  config.ignore_hidden_elements = true
474
- config.default_host = "http://www.example.com"
474
+ config.default_host = 'http://www.example.com'
475
475
  config.automatic_reload = true
476
476
  config.match = :smart
477
477
  config.exact = false
@@ -483,6 +483,7 @@ Capybara.configure do |config|
483
483
  config.enable_aria_label = false
484
484
  config.reuse_server = true
485
485
  config.default_set_options = {}
486
+ config.test_id = nil
486
487
  end
487
488
 
488
489
  Capybara.register_driver :rack_test do |app|
@@ -26,7 +26,7 @@ module Capybara
26
26
  attr_writer :reuse_server
27
27
 
28
28
  def threadsafe=(bool)
29
- raise "Threadsafe setting cannot be changed once a session is created" if (bool != threadsafe) && Session.instance_created?
29
+ raise 'Threadsafe setting cannot be changed once a session is created' if (bool != threadsafe) && Session.instance_created?
30
30
  @threadsafe = bool
31
31
  end
32
32
 
@@ -5,12 +5,12 @@ require 'capybara'
5
5
  module Capybara
6
6
  module DSL
7
7
  def self.included(base)
8
- warn "including Capybara::DSL in the global scope is not recommended!" if base == Object
8
+ warn 'including Capybara::DSL in the global scope is not recommended!' if base == Object
9
9
  super
10
10
  end
11
11
 
12
12
  def self.extended(base)
13
- warn "extending the main object with Capybara::DSL is not recommended!" if base == TOPLEVEL_BINDING.eval("self")
13
+ warn 'extending the main object with Capybara::DSL is not recommended!' if base == TOPLEVEL_BINDING.eval('self')
14
14
  super
15
15
  end
16
16
 
@@ -15,7 +15,7 @@ module Capybara
15
15
  # @return [String] Normalized text
16
16
  #
17
17
  def normalize_whitespace(text)
18
- warn "DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver"
18
+ warn 'DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver'
19
19
  text.to_s.gsub(/[[:space:]]+/, ' ').strip
20
20
  end
21
21
 
@@ -33,7 +33,7 @@ module Capybara
33
33
  return text if text.is_a?(Regexp)
34
34
 
35
35
  escaped = Regexp.escape(text)
36
- escaped = escaped.gsub("\\ ", "[[:blank:]]") if all_whitespace
36
+ escaped = escaped.gsub('\\ ', '[[:blank:]]') if all_whitespace
37
37
  escaped = "\\A#{escaped}\\z" if exact
38
38
  Regexp.new(escaped, options)
39
39
  end
@@ -48,7 +48,7 @@ module Capybara
48
48
  # @return [String] The modified HTML code
49
49
  #
50
50
  def inject_asset_host(html, host: Capybara.asset_host)
51
- if host && Nokogiri::HTML(html).css("base").empty?
51
+ if host && Nokogiri::HTML(html).css('base').empty?
52
52
  match = html.match(/<head[^<]*?>/)
53
53
  return html.clone.insert match.end(0), "<base href='#{host}' />" if match
54
54
  end
@@ -175,13 +175,13 @@ module Capybara
175
175
  end
176
176
 
177
177
  class Capybara::Session
178
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
178
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
179
179
  end
180
180
 
181
181
  class Capybara::Node::Base
182
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
182
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
183
183
  end
184
184
 
185
185
  class Capybara::Node::Simple
186
- include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
186
+ include Capybara::Minitest::Expectations unless ENV['MT_NO_EXPECTATIONS']
187
187
  end
@@ -27,13 +27,13 @@ module Capybara
27
27
 
28
28
  ##
29
29
  #
30
- # Finds a link by id, text or title and clicks it. Also looks at image
30
+ # Finds a link by id, Capybara.test_id attribute, text or title and clicks it. Also looks at image
31
31
  # alt text inside the link.
32
32
  #
33
33
  # @macro waiting_behavior
34
34
  #
35
35
  # @overload click_link([locator], options)
36
- # @param [String] locator text, id, title or nested image's alt attribute
36
+ # @param [String] locator text, id, Capybara.test_id attribute, title or nested image's alt attribute
37
37
  # @param options See {Capybara::Node::Finders#find_link}
38
38
  #
39
39
  # @return [Capybara::Node::Element] The element clicked
@@ -45,7 +45,7 @@ module Capybara
45
45
  #
46
46
  # Finds a button on the page and clicks it.
47
47
  # This can be any \<input> element of type submit, reset, image, button or it can be a
48
- # \<button> element. All buttons can be found by their id, value, or title. \<button> elements can also be found
48
+ # \<button> element. All buttons can be found by their id, Capybara.test_id attribute, value, or title. \<button> elements can also be found
49
49
  # by their text content, and image \<input> elements by their alt attribute
50
50
  #
51
51
  # @macro waiting_behavior
@@ -61,7 +61,7 @@ module Capybara
61
61
  ##
62
62
  #
63
63
  # Locate a text field or text area and fill it in with the given text
64
- # The field can be found via its name, id or label text.
64
+ # The field can be found via its name, id, Capybara.test_id attribute, or label text.
65
65
  #
66
66
  # page.fill_in 'Name', with: 'Bob'
67
67
  #
@@ -80,9 +80,9 @@ module Capybara
80
80
  # @option options [Hash] fill_options Driver specific options regarding how to fill fields (Defaults come from Capybara.default_set_options)
81
81
  #
82
82
  # @return [Capybara::Node::Element] The element filled_in
83
- def fill_in(locator = nil, with:, fill_options: {}, **options)
84
- options[:with] = options.delete(:currently_with) if options.key?(:currently_with)
85
- find(:fillable_field, locator, options).set(with, fill_options)
83
+ def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options)
84
+ find_options[:with] = currently_with if currently_with
85
+ find(:fillable_field, locator, find_options).set(with, fill_options)
86
86
  end
87
87
 
88
88
  # @!macro label_click
@@ -170,13 +170,13 @@ module Capybara
170
170
  # @macro waiting_behavior
171
171
  #
172
172
  # @param value [String] Which option to select
173
- # @param from: [String] The id, name or label of the select box
173
+ # @param from: [String] The id, Capybara.test_id atrtribute, name or label of the select box
174
174
  #
175
175
  # @return [Capybara::Node::Element] The option element selected
176
176
  def select(value = nil, from: nil, **options)
177
177
  el = from ? find_select_or_datalist_input(from, options) : self
178
178
 
179
- if el.respond_to?(:tag_name) && (el.tag_name == "input")
179
+ if el.respond_to?(:tag_name) && (el.tag_name == 'input')
180
180
  select_datalist_option(el, value)
181
181
  else
182
182
  el.find(:option, value, options).select_option
@@ -194,7 +194,7 @@ module Capybara
194
194
  # @macro waiting_behavior
195
195
  #
196
196
  # @param value [String] Which option to unselect
197
- # @param from: [String] The id, name or label of the select box
197
+ # @param from: [String] The id, Capybara.test_id attribute, name or label of the select box
198
198
  #
199
199
  # @return [Capybara::Node::Element] The option element unselected
200
200
  def unselect(value = nil, from: nil, **options)
@@ -205,7 +205,9 @@ module Capybara
205
205
  ##
206
206
  #
207
207
  # Find a file field on the page and attach a file given its path. The file field can
208
- # be found via its name, id or label text.
208
+ # be found via its name, id or label text. In the case of the file field being hidden for
209
+ # styling reasons the `make_visible` option can be used to temporarily change the CSS of
210
+ # the file field, attach the file, and then revert the CSS back to original.
209
211
  #
210
212
  # page.attach_file(locator, '/path/to/file.png')
211
213
  #
@@ -256,11 +258,9 @@ module Capybara
256
258
 
257
259
  def select_datalist_option(input, value)
258
260
  datalist_options = input.evaluate_script(DATALIST_OPTIONS_SCRIPT)
259
- if (option = datalist_options.find { |o| o['value'] == value || o['label'] == value })
260
- input.set(option['value'])
261
- else
262
- raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}")
263
- end
261
+ option = datalist_options.find { |o| o.values_at('value', 'label').include?(value) }
262
+ raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}") unless option
263
+ input.set(option['value'])
264
264
  rescue ::Capybara::NotSupportedByDriverError
265
265
  # Implement for drivers that don't support JS
266
266
  datalist = find(:xpath, XPath.descendant(:datalist)[XPath.attr(:id) == input[:list]], visible: false)
@@ -271,7 +271,7 @@ module Capybara
271
271
  def while_visible(element, visible_css)
272
272
  visible_css = { opacity: 1, display: 'block', visibility: 'visible' } if visible_css == true
273
273
  _update_style(element, visible_css)
274
- raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible" unless element.visible?
274
+ raise ExpectationNotMet, 'The style changes in :make_visible did not make the file input visible' unless element.visible?
275
275
  begin
276
276
  yield element
277
277
  ensure
@@ -282,7 +282,7 @@ module Capybara
282
282
  def _update_style(element, style)
283
283
  element.execute_script(UPDATE_STYLE_SCRIPT, style)
284
284
  rescue Capybara::NotSupportedByDriverError
285
- warn "The :make_visible option is not supported by the current driver - ignoring"
285
+ warn 'The :make_visible option is not supported by the current driver - ignoring'
286
286
  end
287
287
 
288
288
  def _reset_style(element)
@@ -86,7 +86,7 @@ module Capybara
86
86
  raise e unless driver.wait? && catch_error?(e, errors)
87
87
  raise e if timer.expired?
88
88
  sleep(0.05)
89
- raise Capybara::FrozenInTime, "Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead" if timer.stalled?
89
+ raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead' if timer.stalled?
90
90
  reload if session_options.automatic_reload
91
91
  retry
92
92
  ensure
@@ -82,7 +82,7 @@ module Capybara
82
82
  #
83
83
  def style(*styles)
84
84
  styles = styles.flatten.map(&:to_s)
85
- raise ArgumentError, "You must specify at least one CSS style" if styles.empty?
85
+ raise ArgumentError, 'You must specify at least one CSS style' if styles.empty?
86
86
  begin
87
87
  synchronize { base.style(styles) }
88
88
  rescue NotImplementedError => e
@@ -399,7 +399,7 @@ module Capybara
399
399
  def evaluate_script(script, *args)
400
400
  session.evaluate_script(<<~JS, self, *args)
401
401
  (function(){
402
- return #{script}
402
+ return #{script.strip}
403
403
  }).apply(arguments[0], Array.prototype.slice.call(arguments,1));
404
404
  JS
405
405
  end
@@ -89,7 +89,7 @@ module Capybara
89
89
  # Find a form field on the page. The field can be found by its name, id or label text.
90
90
  #
91
91
  # @overload find_field([locator], **options)
92
- # @param [String] locator name, id, placeholder or text of associated label element
92
+ # @param [String] locator name, id, Capybara.test_id attribute, placeholder or text of associated label element
93
93
  #
94
94
  # @macro waiting_behavior
95
95
  #
@@ -120,7 +120,7 @@ module Capybara
120
120
  # Find a link on the page. The link can be found by its id or text.
121
121
  #
122
122
  # @overload find_link([locator], **options)
123
- # @param [String] locator id, title, text, or alt of enclosed img element
123
+ # @param [String] locator id, Capybara.test_id attribute, title, text, or alt of enclosed img element
124
124
  #
125
125
  # @macro waiting_behavior
126
126
  #
@@ -139,11 +139,11 @@ module Capybara
139
139
  #
140
140
  # Find a button on the page.
141
141
  # This can be any \<input> element of type submit, reset, image, button or it can be a
142
- # \<button> element. All buttons can be found by their id, value, or title. \<button> elements can also be found
142
+ # \<button> element. All buttons can be found by their id, Capbyara.test_id attribute, value, or title. \<button> elements can also be found
143
143
  # by their text content, and image \<input> elements by their alt attribute
144
144
  #
145
145
  # @overload find_button([locator], **options)
146
- # @param [String] locator id, value, title, text content, alt of image
146
+ # @param [String] locator id, Capybara.test_id attribute, value, title, text content, alt of image
147
147
  #
148
148
  # @overload find_button(**options)
149
149
  #
@@ -290,8 +290,8 @@ module Capybara
290
290
  result = query.resolve_for(self)
291
291
  end
292
292
 
293
- raise Capybara::Ambiguous, "Ambiguous match, found #{result.size} elements matching #{query.description}" if ambiguous?(query, result)
294
- raise Capybara::ElementNotFound, "Unable to find #{query.description}" if result.empty?
293
+ raise Capybara::Ambiguous, "Ambiguous match, found #{result.size} elements matching #{query.applied_description}" if ambiguous?(query, result)
294
+ raise Capybara::ElementNotFound, "Unable to find #{query.applied_description}" if result.empty?
295
295
 
296
296
  result.first
297
297
  end.tap(&:allow_reload!)
@@ -382,7 +382,7 @@ module Capybara
382
382
  ##
383
383
  #
384
384
  # Checks if the page or current node has a radio button or
385
- # checkbox with the given label, value or id, that is currently
385
+ # checkbox with the given label, value, id, or Capybara.test_id attribute that is currently
386
386
  # checked.
387
387
  #
388
388
  # @param [String] locator The label, name or id of a checked field
@@ -395,7 +395,7 @@ module Capybara
395
395
  ##
396
396
  #
397
397
  # Checks if the page or current node has no radio button or
398
- # checkbox with the given label, value or id, that is currently
398
+ # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
399
399
  # checked.
400
400
  #
401
401
  # @param [String] locator The label, name or id of a checked field
@@ -408,7 +408,7 @@ module Capybara
408
408
  ##
409
409
  #
410
410
  # Checks if the page or current node has a radio button or
411
- # checkbox with the given label, value or id, that is currently
411
+ # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
412
412
  # unchecked.
413
413
  #
414
414
  # @param [String] locator The label, name or id of an unchecked field
@@ -421,7 +421,7 @@ module Capybara
421
421
  ##
422
422
  #
423
423
  # Checks if the page or current node has no radio button or
424
- # checkbox with the given label, value or id, that is currently
424
+ # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
425
425
  # unchecked.
426
426
  #
427
427
  # @param [String] locator The label, name or id of an unchecked field
@@ -520,7 +520,7 @@ module Capybara
520
520
  #
521
521
  def assert_matches_selector(*args, &optional_filter_block)
522
522
  _verify_match_result(args, optional_filter_block) do |result|
523
- raise Capybara::ExpectationNotMet, "Item does not match the provided selector" unless result.include? self
523
+ raise Capybara::ExpectationNotMet, 'Item does not match the provided selector' unless result.include? self
524
524
  end
525
525
  end
526
526
 
@@ -81,7 +81,7 @@ module Capybara
81
81
  if multiple?
82
82
  native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
83
83
  else
84
- option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
84
+ option = native.xpath(".//option[@selected='selected']").first || native.xpath('.//option').first
85
85
  option[:value] || option.content if option
86
86
  end
87
87
  elsif tag_name == 'input' && %w[radio checkbox].include?(native[:type])
@@ -100,7 +100,7 @@ module Capybara
100
100
  # @return [Boolean] Whether the element is visible
101
101
  #
102
102
  def visible?(check_ancestors = true)
103
- return false if (tag_name == 'input') && (native[:type] == "hidden")
103
+ return false if (tag_name == 'input') && (native[:type] == 'hidden')
104
104
 
105
105
  if check_ancestors
106
106
  !native.xpath("boolean(./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head'])")
@@ -12,7 +12,7 @@ module Capybara
12
12
  end
13
13
  end
14
14
 
15
- def description
15
+ def description(applied = false)
16
16
  child_query = @child_node&.instance_variable_get(:@query)
17
17
  desc = super
18
18
  desc += " that is an ancestor of #{child_query.description}" if child_query
@@ -73,15 +73,16 @@ module Capybara
73
73
  end
74
74
 
75
75
  def count_message
76
- message = +""
77
- if options[:count]
78
- message << " #{options[:count]} #{Capybara::Helpers.declension('time', 'times', options[:count])}"
79
- elsif options[:between]
80
- message << " between #{options[:between].first} and #{options[:between].last} times"
81
- elsif options[:maximum]
82
- message << " at most #{options[:maximum]} #{Capybara::Helpers.declension('time', 'times', options[:maximum])}"
83
- elsif options[:minimum]
84
- message << " at least #{options[:minimum]} #{Capybara::Helpers.declension('time', 'times', options[:minimum])}"
76
+ message = +''
77
+ count, between, maximum, minimum = options.values_at(:count, :between, :maximum, :minimum)
78
+ if count
79
+ message << " #{count} #{Capybara::Helpers.declension('time', 'times', count)}"
80
+ elsif between
81
+ message << " between #{between.first} and #{between.last} times"
82
+ elsif maximum
83
+ message << " at most #{maximum} #{Capybara::Helpers.declension('time', 'times', maximum)}"
84
+ elsif minimum
85
+ message << " at least #{minimum} #{Capybara::Helpers.declension('time', 'times', minimum)}"
85
86
  end
86
87
  message
87
88
  end
@@ -90,8 +91,8 @@ module Capybara
90
91
  invalid_keys = @options.keys - valid_keys
91
92
  return if invalid_keys.empty?
92
93
 
93
- invalid_names = invalid_keys.map(&:inspect).join(", ")
94
- valid_names = valid_keys.map(&:inspect).join(", ")
94
+ invalid_names = invalid_keys.map(&:inspect).join(', ')
95
+ valid_names = valid_keys.map(&:inspect).join(', ')
95
96
  raise ArgumentError, "invalid keys #{invalid_names}, should be one of #{valid_names}"
96
97
  end
97
98
  end