capybara 3.3.1 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
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