capybara 3.2.1 → 3.3.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +22 -1
  3. data/README.md +1 -1
  4. data/lib/capybara.rb +2 -0
  5. data/lib/capybara/driver/base.rb +5 -1
  6. data/lib/capybara/driver/node.rb +4 -0
  7. data/lib/capybara/helpers.rb +25 -0
  8. data/lib/capybara/minitest.rb +7 -1
  9. data/lib/capybara/minitest/spec.rb +8 -1
  10. data/lib/capybara/node/base.rb +3 -3
  11. data/lib/capybara/node/element.rb +52 -0
  12. data/lib/capybara/node/matchers.rb +33 -0
  13. data/lib/capybara/queries/selector_query.rb +4 -4
  14. data/lib/capybara/queries/style_query.rb +41 -0
  15. data/lib/capybara/rack_test/browser.rb +7 -1
  16. data/lib/capybara/rack_test/node.rb +4 -0
  17. data/lib/capybara/rspec/compound.rb +67 -65
  18. data/lib/capybara/rspec/features.rb +2 -4
  19. data/lib/capybara/rspec/matchers.rb +30 -10
  20. data/lib/capybara/selector.rb +9 -0
  21. data/lib/capybara/selector/css.rb +74 -1
  22. data/lib/capybara/selector/filters/base.rb +2 -1
  23. data/lib/capybara/selector/filters/expression_filter.rb +2 -1
  24. data/lib/capybara/selector/selector.rb +1 -1
  25. data/lib/capybara/selenium/driver.rb +34 -43
  26. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +35 -0
  27. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +31 -0
  28. data/lib/capybara/selenium/node.rb +17 -20
  29. data/lib/capybara/selenium/nodes/marionette_node.rb +31 -0
  30. data/lib/capybara/server.rb +8 -29
  31. data/lib/capybara/server/checker.rb +38 -0
  32. data/lib/capybara/spec/public/test.js +5 -0
  33. data/lib/capybara/spec/session/all_spec.rb +4 -0
  34. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  35. data/lib/capybara/spec/session/click_button_spec.rb +10 -0
  36. data/lib/capybara/spec/session/click_link_spec.rb +11 -0
  37. data/lib/capybara/spec/session/fill_in_spec.rb +2 -0
  38. data/lib/capybara/spec/session/find_link_spec.rb +18 -0
  39. data/lib/capybara/spec/session/find_spec.rb +1 -0
  40. data/lib/capybara/spec/session/first_spec.rb +1 -0
  41. data/lib/capybara/spec/session/has_css_spec.rb +0 -6
  42. data/lib/capybara/spec/session/has_style_spec.rb +25 -0
  43. data/lib/capybara/spec/session/node_spec.rb +34 -0
  44. data/lib/capybara/spec/session/save_page_spec.rb +4 -1
  45. data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -1
  46. data/lib/capybara/spec/session/text_spec.rb +1 -0
  47. data/lib/capybara/spec/session/title_spec.rb +1 -0
  48. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  49. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  50. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -0
  51. data/lib/capybara/spec/session/window/window_spec.rb +20 -0
  52. data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
  53. data/lib/capybara/spec/session/window/within_window_spec.rb +1 -0
  54. data/lib/capybara/spec/session/within_spec.rb +1 -0
  55. data/lib/capybara/spec/spec_helper.rb +3 -1
  56. data/lib/capybara/spec/test_app.rb +18 -0
  57. data/lib/capybara/spec/views/form.erb +8 -0
  58. data/lib/capybara/spec/views/tables.erb +1 -1
  59. data/lib/capybara/spec/views/with_html.erb +9 -2
  60. data/lib/capybara/spec/views/with_js.erb +4 -0
  61. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  62. data/lib/capybara/version.rb +1 -1
  63. data/lib/capybara/window.rb +11 -0
  64. data/spec/css_splitter_spec.rb +38 -0
  65. data/spec/dsl_spec.rb +1 -1
  66. data/spec/minitest_spec.rb +7 -1
  67. data/spec/minitest_spec_spec.rb +8 -1
  68. data/spec/rack_test_spec.rb +10 -0
  69. data/spec/rspec/shared_spec_matchers.rb +2 -0
  70. data/spec/selenium_spec_chrome.rb +28 -0
  71. data/spec/selenium_spec_chrome_remote.rb +2 -2
  72. data/spec/selenium_spec_marionette.rb +21 -1
  73. data/spec/server_spec.rb +0 -1
  74. data/spec/shared_selenium_session.rb +16 -1
  75. metadata +18 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7a05e30cbe8690367f383d17347c7b804e4d344ad3133ade68455a048b42808
4
- data.tar.gz: b636d45641d3a1984b28efb9cd1079df36e7f41bf7ae0dc99335aa36e925951a
3
+ metadata.gz: ec1af73714c227e46b54e14d716a63f2cc75011d2cb8f0fde62eecb8d5d07785
4
+ data.tar.gz: 907fecc783f2a9b23529e10b0e4775dc0f1015ffc5163157523772d192456e5f
5
5
  SHA512:
6
- metadata.gz: 0e7499bd3c7f96850db011ebf6215c8e27e11cfcc0c9a000a12b655455d03969fcaa8b17d09cbb4e672ff5ac3eaeb84d45e98d556bc26c42f4f0e0f9b55a7573
7
- data.tar.gz: '053149fbaa728ab525ed988ef231fcc8189db64baf64fc6be64df8d05c86bd9ca13023028fdd1fe92751fc7345df2e4930e3cccf20306c7805265c27ee09518e'
6
+ metadata.gz: f5c6f7cdf74cb231ee795c299f7ee28688dc8ecfd371b97c1744e77a823209e5270626cdf36e8c171fe1018394d1f1176b15e0b61e88e18f4c60ff402d1aad88
7
+ data.tar.gz: 29fcba8784b579ff159a00df91ddf83aa0cdc14fb6061535943933aa89796848068b8dea1da723cdaeda9ec3a3c81c8ce7fb7857f052b3764ffe7cbcea790d93
data/History.md CHANGED
@@ -1,3 +1,24 @@
1
+ # Version 3.3.0
2
+ Release date: 2018-06-25
3
+
4
+ ### Added
5
+
6
+ * RackTest driver now handles 307/308 redirects
7
+ * `execute_async_script` can now be called on elements to run the JS in the context of the element
8
+ * `:download` filter option on `:link' selector
9
+ * `Window#fullscreen`
10
+ * `Element#style` and associated matchers
11
+
12
+ ### Changed
13
+
14
+ * Minimum "supported" `selenium-webdriver` is raised to 3.5.0 (but you really should be using newer than that)
15
+
16
+ ### Fixes
17
+
18
+ * Selenium driver with Firefox workaround for clicking on table row - https://github.com/mozilla/geckodriver/issues/1228
19
+ * :class and :id filters applied to CSS based selectors now correctly handle the CSS comma
20
+ * Selenium driver handles namespaces when generating an elements `#path` - Issue #2048
21
+
1
22
  # Version 3.2.1
2
23
  Release date: 2018-06-04
3
24
 
@@ -17,7 +38,7 @@ Release date: 2018-06-01
17
38
  ### Added
18
39
 
19
40
  * New global configuration `default_set_options` used in `Capybara::Node::Element#set` as default `options` hash [Champier Cyril]
20
- * `execute_javascript` and `evaluate_javascript` can now be called on elements to run the JS in the context of the element [Thomas Walpole]
41
+ * `execute_script` and `evaluate_script` can now be called on elements to run the JS in the context of the element [Thomas Walpole]
21
42
  * Filters in custom selectors now support a `matcher` Regexp to handle multiple filter options [Thomas Walpole]
22
43
  * `:element` selector type which will match on any attribute (other than the reserved names) passed as a filter option [Thomas Walpole]
23
44
  * `:class` filter option now supports preceding class names with `!` to indicate not having that class [Thomas Walpole]
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/teamcapybara/capybara.svg)](https://travis-ci.org/teamcapybara/capybara)
4
4
  [![Build Status](https://ci.appveyor.com/api/projects/status/github/teamcapybara/capybara?svg=true)](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
5
- [![Dependency Status](https://gemnasium.com/teamcapybara/capybara.svg)](https://gemnasium.com/teamcapybara/capybara)
6
5
  [![Code Climate](https://codeclimate.com/github/teamcapybara/capybara.svg)](https://codeclimate.com/github/teamcapybara/capybara)
7
6
  [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
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
10
  you can find the README at https://github.com/teamcapybara/capybara/blob/3.2_stable/README.md
@@ -406,6 +406,7 @@ module Capybara
406
406
  require 'capybara/queries/match_query'
407
407
  require 'capybara/queries/ancestor_query'
408
408
  require 'capybara/queries/sibling_query'
409
+ require 'capybara/queries/style_query'
409
410
 
410
411
  require 'capybara/node/finders'
411
412
  require 'capybara/node/matchers'
@@ -426,6 +427,7 @@ module Capybara
426
427
  require 'capybara/rack_test/css_handlers.rb'
427
428
 
428
429
  require 'capybara/selenium/node'
430
+ require 'capybara/selenium/nodes/marionette_node'
429
431
  require 'capybara/selenium/driver'
430
432
  end
431
433
 
@@ -90,7 +90,11 @@ class Capybara::Driver::Base
90
90
  end
91
91
 
92
92
  def maximize_window(handle)
93
- raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_current_window'
93
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_window'
94
+ end
95
+
96
+ def fullscreen_window(handle)
97
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#fullscreen_window'
94
98
  end
95
99
 
96
100
  def close_window(handle)
@@ -26,6 +26,10 @@ module Capybara
26
26
  raise NotImplementedError
27
27
  end
28
28
 
29
+ def style(styles)
30
+ raise NotImplementedError
31
+ end
32
+
29
33
  # @param value String or Array. Array is only allowed if node has 'multiple' attribute
30
34
  # @param options [Hash{}] Driver specific options for how to set a value on a node
31
35
  def set(value, **options)
@@ -74,5 +74,30 @@ module Capybara
74
74
  else
75
75
  def monotonic_time; Time.now.to_f; end
76
76
  end
77
+
78
+ def timer(expire_in:)
79
+ Timer.new(expire_in)
80
+ end
81
+
82
+ class Timer
83
+ def initialize(expire_in)
84
+ @start = current
85
+ @expire_in = expire_in
86
+ end
87
+
88
+ def expired?
89
+ current - @start >= @expire_in
90
+ end
91
+
92
+ def stalled?
93
+ @start == current
94
+ end
95
+
96
+ private
97
+
98
+ def current
99
+ Capybara::Helpers.monotonic_time
100
+ end
101
+ end
77
102
  end
78
103
  end
@@ -81,9 +81,15 @@ module Capybara
81
81
  # @!method assert_xpath
82
82
  # see {Capybara::Node::Matchers#assert_not_matches_selector}
83
83
 
84
+ ## Assert element has the provided CSS styles
85
+ #
86
+ # @!method assert_style
87
+ # see {Capybara::Node::Matchers#assert_style}
88
+
84
89
  %w[assert_selector assert_no_selector
85
90
  assert_all_of_selectors assert_none_of_selectors
86
- assert_matches_selector assert_not_matches_selector].each do |assertion_name|
91
+ assert_matches_selector assert_not_matches_selector
92
+ assert_style].each do |assertion_name|
87
93
  class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
88
94
  def #{assertion_name} *args, &optional_filter_block
89
95
  self.assertions +=1
@@ -15,7 +15,8 @@ module Capybara
15
15
  [%W[assert_#{assertion} must_have_#{assertion}],
16
16
  %W[refute_#{assertion} wont_have_#{assertion}]]
17
17
  end + [%w[assert_all_of_selectors must_have_all_of_selectors],
18
- %w[assert_none_of_selectors must_have_none_of_selectors]] +
18
+ %w[assert_none_of_selectors must_have_none_of_selectors],
19
+ %w[assert_style must_have_style]] +
19
20
  %w[selector xpath css].flat_map do |assertion|
20
21
  [%W[assert_matches_#{assertion} must_match_#{assertion}],
21
22
  %W[refute_matches_#{assertion} wont_match_#{assertion}]]
@@ -163,6 +164,12 @@ module Capybara
163
164
  #
164
165
  # @!method wont_have_current_path
165
166
  # see {Capybara::SessionMatchers#assert_no_current_path}
167
+
168
+ ##
169
+ # Expectation that element has style
170
+ #
171
+ # @!method must_have_style
172
+ # see {Capybara::SessionMatchers#assert_style}
166
173
  end
167
174
  end
168
175
  end
@@ -78,15 +78,15 @@ module Capybara
78
78
  yield
79
79
  else
80
80
  session.synchronized = true
81
- start_time = Capybara::Helpers.monotonic_time
81
+ timer = Capybara::Helpers.timer(expire_in: seconds)
82
82
  begin
83
83
  yield
84
84
  rescue StandardError => e
85
85
  session.raise_server_error!
86
86
  raise e unless driver.wait? && catch_error?(e, errors)
87
- raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds
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 Capybara::Helpers.monotonic_time == start_time
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
@@ -71,6 +71,29 @@ module Capybara
71
71
  synchronize { base[attribute] }
72
72
  end
73
73
 
74
+ ##
75
+ #
76
+ # Retrieve the given CSS styles
77
+ #
78
+ # element.style('color', 'font-size') # => Computed values of CSS 'color' and 'font-size' styles
79
+ #
80
+ # @param [String] Names of the desired CSS properties
81
+ # @return [Hash] Hash of the CSS property names to computed values
82
+ #
83
+ def style(*styles)
84
+ styles = styles.flatten.map(&:to_s)
85
+ raise ArgumentError, "You must specify at least one CSS style" if styles.empty?
86
+ begin
87
+ synchronize { base.style(styles) }
88
+ rescue NotImplementedError => e
89
+ begin
90
+ evaluate_script(STYLE_SCRIPT, *styles)
91
+ rescue Capybara::NotSupportedByDriverError
92
+ raise e
93
+ end
94
+ end
95
+ end
96
+
74
97
  ##
75
98
  #
76
99
  # @return [String] The value of the form element
@@ -381,6 +404,23 @@ module Capybara
381
404
  JS
382
405
  end
383
406
 
407
+ ##
408
+ #
409
+ # Evaluate the given JavaScript in the context of the element and obtain the result from a
410
+ # callback function which will be passed as the last argument to the script. `this` in the
411
+ # script will refer to the element this is called on
412
+ #
413
+ # @param [String] script A string of JavaScript to evaluate
414
+ # @return [Object] The result of the evaluated JavaScript (may be driver specific)
415
+ #
416
+ def evaluate_async_script(script, *args)
417
+ session.evaluate_async_script(<<~JS, self, *args)
418
+ (function (){
419
+ #{script}
420
+ }).apply(arguments[0], Array.prototype.slice.call(arguments,1));
421
+ JS
422
+ end
423
+
384
424
  def reload
385
425
  if @allow_reload
386
426
  begin
@@ -402,6 +442,18 @@ module Capybara
402
442
 
403
443
  %(Obsolete #<Capybara::Node::Element>)
404
444
  end
445
+
446
+ STYLE_SCRIPT = <<~JS
447
+ (function(){
448
+ var s = window.getComputedStyle(this);
449
+ var result = {};
450
+ for (var i = arguments.length; i--; ) {
451
+ var property_name = arguments[i];
452
+ result[property_name] = s.getPropertyValue(property_name);
453
+ }
454
+ return result;
455
+ }).apply(this, arguments)
456
+ JS
405
457
  end
406
458
  end
407
459
  end
@@ -56,6 +56,21 @@ module Capybara
56
56
  false
57
57
  end
58
58
 
59
+ ##
60
+ #
61
+ # Checks if a an element has the specified CSS styles
62
+ #
63
+ # element.has_style?( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
64
+ #
65
+ # @param styles [Hash]
66
+ # @return [Boolean] If the styles match
67
+ #
68
+ def has_style?(styles, **options)
69
+ assert_style(styles, **options)
70
+ rescue Capybara::ExpectationNotMet
71
+ false
72
+ end
73
+
59
74
  ##
60
75
  #
61
76
  # Asserts that a given selector is on the page or a descendant of the current node.
@@ -97,6 +112,24 @@ module Capybara
97
112
  end
98
113
  end
99
114
 
115
+ ##
116
+ #
117
+ # Asserts that an element has the specified CSS styles
118
+ #
119
+ # element.assert_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
120
+ #
121
+ # @param styles [Hash]
122
+ # @raise [Capybara::ExpectationNotMet] If the element doesn't have the specified styles
123
+ #
124
+ def assert_style(styles, **options)
125
+ query_args = _set_query_session_options(styles, options)
126
+ query = Capybara::Queries::StyleQuery.new(*query_args)
127
+ synchronize(query.wait) do
128
+ raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
129
+ end
130
+ true
131
+ end
132
+
100
133
  # Asserts that all of the provided selectors are present on the given page
101
134
  # or descendants of the current node. If options are provided, the assertion
102
135
  # will check that each locator is present with those options as well (other than :wait).
@@ -225,14 +225,14 @@ module Capybara
225
225
  raise ArgumentError, "XPath expressions are not supported for the :class filter with CSS based selectors"
226
226
  end
227
227
 
228
- if process_class || process_id
229
- css_selectors = expr.split(',').map(&:rstrip)
230
- expr = css_selectors.map do |sel|
231
- sel += "##{Capybara::Selector::CSS.escape(options[:id])}" if process_id
228
+ if process_id || process_class
229
+ expr = ::Capybara::Selector::CSS.split(expr).map do |sel|
230
+ sel += "##{::Capybara::Selector::CSS.escape(options[:id])}" if process_id
232
231
  sel += css_from_classes(Array(options[:class])) if process_class
233
232
  sel
234
233
  end.join(", ")
235
234
  end
235
+
236
236
  expr
237
237
  end
238
238
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capybara
4
+ # @api private
5
+ module Queries
6
+ class StyleQuery < BaseQuery
7
+ def initialize(expected_styles, session_options:, **options)
8
+ @expected_styles = expected_styles.each_with_object({}) { |(style, value), str_keys| str_keys[style.to_s] = value }
9
+ @options = options
10
+ @actual_styles = {}
11
+ super(@options)
12
+ self.session_options = session_options
13
+
14
+ assert_valid_keys
15
+ end
16
+
17
+ def resolves_for?(node)
18
+ @node = node
19
+ @actual_styles = node.style(*@expected_styles.keys)
20
+ @expected_styles.all? do |style, value|
21
+ if value.is_a? Regexp
22
+ @actual_styles[style] =~ value
23
+ else
24
+ @actual_styles[style] == value
25
+ end
26
+ end
27
+ end
28
+
29
+ def failure_message
30
+ +"Expected node to have styles #{@expected_styles.inspect}. " \
31
+ "Actual styles were #{@actual_styles.inspect}"
32
+ end
33
+
34
+ private
35
+
36
+ def valid_keys
37
+ %i[wait]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -44,7 +44,13 @@ class Capybara::RackTest::Browser
44
44
  return unless driver.follow_redirects?
45
45
 
46
46
  driver.redirect_limit.times do
47
- process(:get, last_response["Location"], {}, env) if last_response.redirect?
47
+ if last_response.redirect?
48
+ if [307, 308].include? last_response.status
49
+ process(last_request.request_method, last_response["Location"], last_request.params, env)
50
+ else
51
+ process(:get, last_response["Location"], {}, env)
52
+ end
53
+ end
48
54
  end
49
55
  raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
50
56
  end
@@ -24,6 +24,10 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
24
24
  string_node[name]
25
25
  end
26
26
 
27
+ def style(_styles)
28
+ raise NotImplementedError, "The rack_test driver does not process CSS"
29
+ end
30
+
27
31
  def value
28
32
  string_node.value
29
33
  end
@@ -1,89 +1,91 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Capybara
4
- module RSpecMatchers
5
- module Compound
6
- include ::RSpec::Matchers::Composable
3
+ if defined?(::RSpec::Expectations::Version)
4
+ module Capybara
5
+ module RSpecMatchers
6
+ module Compound
7
+ include ::RSpec::Matchers::Composable
7
8
 
8
- def and(matcher)
9
- And.new(self, matcher)
10
- end
11
-
12
- def and_then(matcher)
13
- ::RSpec::Matchers::BuiltIn::Compound::And.new(self, matcher)
14
- end
15
-
16
- def or(matcher)
17
- Or.new(self, matcher)
18
- end
9
+ def and(matcher)
10
+ And.new(self, matcher)
11
+ end
19
12
 
20
- class CapybaraEvaluator
21
- def initialize(actual)
22
- @actual = actual
23
- @match_results = Hash.new { |h, matcher| h[matcher] = matcher.matches?(@actual) }
13
+ def and_then(matcher)
14
+ ::RSpec::Matchers::BuiltIn::Compound::And.new(self, matcher)
24
15
  end
25
16
 
26
- def matcher_matches?(matcher)
27
- @match_results[matcher]
17
+ def or(matcher)
18
+ Or.new(self, matcher)
28
19
  end
29
20
 
30
- def reset
31
- @match_results.clear
21
+ class CapybaraEvaluator
22
+ def initialize(actual)
23
+ @actual = actual
24
+ @match_results = Hash.new { |h, matcher| h[matcher] = matcher.matches?(@actual) }
25
+ end
26
+
27
+ def matcher_matches?(matcher)
28
+ @match_results[matcher]
29
+ end
30
+
31
+ def reset
32
+ @match_results.clear
33
+ end
32
34
  end
33
- end
34
35
 
35
- class And < ::RSpec::Matchers::BuiltIn::Compound::And
36
- private
36
+ class And < ::RSpec::Matchers::BuiltIn::Compound::And
37
+ private
37
38
 
38
- def match(_expected, actual)
39
- @evaluator = CapybaraEvaluator.new(actual)
40
- syncer = sync_element(actual)
41
- begin
42
- syncer.synchronize do
43
- @evaluator.reset
44
- raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].all?
45
- true
39
+ def match(_expected, actual)
40
+ @evaluator = CapybaraEvaluator.new(actual)
41
+ syncer = sync_element(actual)
42
+ begin
43
+ syncer.synchronize do
44
+ @evaluator.reset
45
+ raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].all?
46
+ true
47
+ end
48
+ rescue StandardError
49
+ false
46
50
  end
47
- rescue StandardError
48
- false
49
51
  end
50
- end
51
52
 
52
- def sync_element(el)
53
- if el.respond_to? :synchronize
54
- el
55
- elsif el.respond_to? :current_scope
56
- el.current_scope
57
- else
58
- Capybara.string(el)
53
+ def sync_element(el)
54
+ if el.respond_to? :synchronize
55
+ el
56
+ elsif el.respond_to? :current_scope
57
+ el.current_scope
58
+ else
59
+ Capybara.string(el)
60
+ end
59
61
  end
60
62
  end
61
- end
62
63
 
63
- class Or < ::RSpec::Matchers::BuiltIn::Compound::Or
64
- private
64
+ class Or < ::RSpec::Matchers::BuiltIn::Compound::Or
65
+ private
65
66
 
66
- def match(_expected, actual)
67
- @evaluator = CapybaraEvaluator.new(actual)
68
- syncer = sync_element(actual)
69
- begin
70
- syncer.synchronize do
71
- @evaluator.reset
72
- raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].any?
73
- true
67
+ def match(_expected, actual)
68
+ @evaluator = CapybaraEvaluator.new(actual)
69
+ syncer = sync_element(actual)
70
+ begin
71
+ syncer.synchronize do
72
+ @evaluator.reset
73
+ raise ::Capybara::ElementNotFound unless [matcher_1_matches?, matcher_2_matches?].any?
74
+ true
75
+ end
76
+ rescue StandardError
77
+ false
74
78
  end
75
- rescue StandardError
76
- false
77
79
  end
78
- end
79
80
 
80
- def sync_element(el)
81
- if el.respond_to? :synchronize
82
- el
83
- elsif el.respond_to? :current_scope
84
- el.current_scope
85
- else
86
- Capybara.string(el)
81
+ def sync_element(el)
82
+ if el.respond_to? :synchronize
83
+ el
84
+ elsif el.respond_to? :current_scope
85
+ el.current_scope
86
+ else
87
+ Capybara.string(el)
88
+ end
87
89
  end
88
90
  end
89
91
  end