capybara 3.2.1 → 3.3.0

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