capybara 3.10.1 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +13 -0
- data/README.md +2 -3
- data/lib/capybara.rb +16 -6
- data/lib/capybara/minitest.rb +8 -9
- data/lib/capybara/node/actions.rb +31 -28
- data/lib/capybara/node/base.rb +2 -1
- data/lib/capybara/node/document_matchers.rb +6 -2
- data/lib/capybara/node/element.rb +10 -10
- data/lib/capybara/node/finders.rb +13 -14
- data/lib/capybara/node/matchers.rb +1 -3
- data/lib/capybara/node/simple.rb +10 -2
- data/lib/capybara/queries/base_query.rb +7 -3
- data/lib/capybara/queries/selector_query.rb +60 -34
- data/lib/capybara/queries/style_query.rb +5 -1
- data/lib/capybara/queries/text_query.rb +2 -2
- data/lib/capybara/queries/title_query.rb +1 -1
- data/lib/capybara/rack_test/node.rb +16 -2
- data/lib/capybara/result.rb +9 -4
- data/lib/capybara/rspec/features.rb +4 -4
- data/lib/capybara/rspec/matcher_proxies.rb +3 -1
- data/lib/capybara/rspec/matchers.rb +25 -287
- data/lib/capybara/rspec/matchers/base.rb +98 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_style.rb +23 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/selector.rb +48 -20
- data/lib/capybara/selector/builders/xpath_builder.rb +3 -3
- data/lib/capybara/selector/css.rb +5 -5
- data/lib/capybara/selector/filters/base.rb +11 -3
- data/lib/capybara/selector/filters/expression_filter.rb +3 -3
- data/lib/capybara/selector/filters/node_filter.rb +16 -2
- data/lib/capybara/selector/regexp_disassembler.rb +116 -17
- data/lib/capybara/selector/selector.rb +52 -26
- data/lib/capybara/selenium/driver.rb +6 -2
- data/lib/capybara/selenium/node.rb +15 -14
- data/lib/capybara/selenium/nodes/marionette_node.rb +19 -5
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -3
- data/lib/capybara/server.rb +6 -1
- data/lib/capybara/server/animation_disabler.rb +1 -1
- data/lib/capybara/session.rb +4 -2
- data/lib/capybara/session/matchers.rb +7 -3
- data/lib/capybara/spec/public/test.js +5 -5
- data/lib/capybara/spec/session/all_spec.rb +5 -0
- data/lib/capybara/spec/session/has_css_spec.rb +4 -4
- data/lib/capybara/spec/session/has_field_spec.rb +17 -0
- data/lib/capybara/spec/session/node_spec.rb +45 -4
- data/lib/capybara/spec/spec_helper.rb +6 -1
- data/lib/capybara/spec/views/frame_child.erb +1 -1
- data/lib/capybara/spec/views/obscured.erb +44 -0
- data/lib/capybara/spec/views/with_html.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/spec/rack_test_spec.rb +15 -0
- data/spec/regexp_dissassembler_spec.rb +88 -8
- data/spec/selector_spec.rb +3 -0
- data/spec/selenium_spec_chrome.rb +9 -15
- data/spec/selenium_spec_chrome_remote.rb +3 -2
- data/spec/selenium_spec_firefox_remote.rb +6 -2
- metadata +54 -3
- data/lib/capybara/rspec/compound.rb +0 -86
data/lib/capybara/version.rb
CHANGED
data/spec/rack_test_spec.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
+
nokogumbo_required = begin
|
5
|
+
require 'nokogumbo'
|
6
|
+
true
|
7
|
+
rescue LoadError
|
8
|
+
false
|
9
|
+
end
|
4
10
|
|
5
11
|
module TestSessions
|
6
12
|
RackTest = Capybara::Session.new(:rack_test, TestApp)
|
@@ -231,6 +237,15 @@ RSpec.describe Capybara::RackTest::Driver do
|
|
231
237
|
end
|
232
238
|
end
|
233
239
|
|
240
|
+
RSpec.describe 'Capybara::String' do
|
241
|
+
it 'should use gumbo' do
|
242
|
+
skip 'Only valid if gumbo is included' unless nokogumbo_required
|
243
|
+
allow(Nokogiri).to receive(:HTML5).and_call_original
|
244
|
+
Capybara.string('<div id=test_div></div>')
|
245
|
+
expect(Nokogiri).to have_received(:HTML5)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
234
249
|
module CSSHandlerIncludeTester
|
235
250
|
def dont_extend_css_handler
|
236
251
|
raise 'should never be called'
|
@@ -27,18 +27,37 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
|
|
27
27
|
/abc./ => %w[abc],
|
28
28
|
/abc.*/ => %w[abc],
|
29
29
|
/abc.def/ => %w[abc def],
|
30
|
-
/abc.def.ghi/ => %w[abc def ghi]
|
30
|
+
/abc.def.ghi/ => %w[abc def ghi],
|
31
|
+
/abc.abcd.abcde/ => %w[abcde],
|
32
|
+
/.*/ => []
|
31
33
|
)
|
32
34
|
end
|
33
35
|
|
34
|
-
it '
|
35
|
-
|
36
|
+
it 'ignores optional characters for substrings' do
|
37
|
+
{
|
36
38
|
/abc*def/ => %w[ab def],
|
37
39
|
/abc*/ => %w[ab],
|
40
|
+
/c*/ => [],
|
38
41
|
/abc?def/ => %w[ab def],
|
39
42
|
/abc?/ => %w[ab],
|
40
43
|
/abc?def?/ => %w[ab de],
|
41
|
-
/abc?def?g/ => %w[ab de g]
|
44
|
+
/abc?def?g/ => %w[ab de g],
|
45
|
+
/d?/ => []
|
46
|
+
}.each do |regexp, expected|
|
47
|
+
expect(Capybara::Selector::RegexpDisassembler.new(regexp).substrings).to eq expected
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'handles optional characters for #alternated_substrings' do
|
52
|
+
verify_alternated_strings(
|
53
|
+
/abc*def/ => [%w[ab def]],
|
54
|
+
/abc*/ => [%w[ab]],
|
55
|
+
/c*/ => [],
|
56
|
+
/abc?def/ => [%w[abdef], %w[abcdef]],
|
57
|
+
/abc?/ => [%w[ab]],
|
58
|
+
/abc?def?/ => [%w[abde], %w[abcde]],
|
59
|
+
/abc?def?g/ => [%w[abdeg], %w[abdefg], %w[abcdeg], %w[abcdefg]],
|
60
|
+
/d?/ => []
|
42
61
|
)
|
43
62
|
end
|
44
63
|
|
@@ -47,7 +66,7 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
|
|
47
66
|
/abc[a-z]/ => %w[abc],
|
48
67
|
/abc[a-z]def[0-9]g/ => %w[abc def g],
|
49
68
|
/[0-9]abc/ => %w[abc],
|
50
|
-
/[0-9]+/ =>
|
69
|
+
/[0-9]+/ => [],
|
51
70
|
/abc[0-9&&[^7]]/ => %w[abc]
|
52
71
|
)
|
53
72
|
end
|
@@ -88,11 +107,64 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
|
|
88
107
|
)
|
89
108
|
end
|
90
109
|
|
91
|
-
it '
|
92
|
-
|
110
|
+
it 'ignores alternation for #substrings' do
|
111
|
+
{
|
93
112
|
/abc|def/ => [],
|
94
113
|
/ab(?:c|d)/ => %w[ab],
|
95
|
-
/ab(c|d)
|
114
|
+
/ab(c|d|e)fg/ => %w[ab fg],
|
115
|
+
/ab?(c|d)fg/ => %w[a fg],
|
116
|
+
/ab(c|d)ef/ => %w[ab ef],
|
117
|
+
/ab(cd?|ef)g/ => %w[ab g],
|
118
|
+
/ab(cd|ef*)g/ => %w[ab g],
|
119
|
+
/ab|cd*/ => [],
|
120
|
+
/cd(?:ef|gh)|xyz/ => [],
|
121
|
+
/(cd(?:ef|gh)|xyz)/ => [],
|
122
|
+
/cd(ef|gh)+/ => %w[cd],
|
123
|
+
/cd(ef|gh)?/ => %w[cd],
|
124
|
+
/cd(ef|gh)?ij/ => %w[cd ij],
|
125
|
+
/cd(ef|gh)+ij/ => %w[cd ij],
|
126
|
+
/cd(ef|gh){2}ij/ => %w[cd ij],
|
127
|
+
/(cd(ef|g*))/ => %w[cd],
|
128
|
+
/ab(cd){0,2}ef/ => %w[ab ef],
|
129
|
+
/ab(cd){0,1}ef/ => %w[ab ef],
|
130
|
+
/ab(cd|cd)ef/ => %w[ab ef],
|
131
|
+
/ab(cd|cd)?ef/ => %w[ab ef],
|
132
|
+
/ab\\?cd/ => %w[ab cd]
|
133
|
+
}.each do |regexp, expected|
|
134
|
+
expect(Capybara::Selector::RegexpDisassembler.new(regexp).substrings).to eq expected
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'handles alternation for #alternated_substrings' do
|
139
|
+
verify_alternated_strings(
|
140
|
+
/abc|def/ => [%w[abc], %w[def]],
|
141
|
+
/ab(?:c|d)/ => [%w[abc], %w[abd]],
|
142
|
+
/ab(c|d|e)fg/ => [%w[abcfg], %w[abdfg], %w[abefg]],
|
143
|
+
/ab?(c|d)fg/ => [%w[acfg], %w[adfg], %w[abcfg], %w[abdfg]],
|
144
|
+
/ab(c|d)ef/ => [%w[abcef], %w[abdef]],
|
145
|
+
/ab(cd?|ef)g/ => [%w[abcg], %w[abcdg], %w[abefg]],
|
146
|
+
/ab(cd|ef*)g/ => [%w[abcdg], %w[abe g]],
|
147
|
+
/ab|cd*/ => [%w[ab], %w[c]],
|
148
|
+
/cd(?:ef|gh)|xyz/ => [%w[cdef], %w[cdgh], %w[xyz]],
|
149
|
+
/(cd(?:ef|gh)|xyz)/ => [%w[cdef], %w[cdgh], %w[xyz]],
|
150
|
+
/cd(ef|gh)+/ => [%w[cdef], %w[cdgh]],
|
151
|
+
/cd(ef|gh)?/ => [%w[cd]],
|
152
|
+
/cd(ef|gh)?ij/ => [%w[cdij], %w[cdefij], %w[cdghij]],
|
153
|
+
/cd(ef|gh)+ij/ => [%w[cdef ij], %w[cdgh ij]],
|
154
|
+
/cd(ef|gh){2}ij/ => [%w[cdefefij], %w[cdefghij], %w[cdghefij], %w[cdghghij]],
|
155
|
+
/(cd(ef|g*))/ => [%w[cd]],
|
156
|
+
/a|b*/ => [],
|
157
|
+
/ab(?:c|d?)/ => [%w[ab]],
|
158
|
+
/ab(c|d)|a*/ => [],
|
159
|
+
/(abc)?(d|e)/ => [%w[d], %w[e]],
|
160
|
+
/(abc*de)?(d|e)/ => [%w[d], %w[e]],
|
161
|
+
/(abc*de)?(d|e?)/ => [],
|
162
|
+
/(abc)?(d|e?)/ => [],
|
163
|
+
/ab(cd){0,2}ef/ => [%w[ab ef]],
|
164
|
+
/ab(cd){0,1}ef/ => [%w[abef], %w[abcdef]],
|
165
|
+
/ab(cd|cd)ef/ => [%w[abcdef]],
|
166
|
+
/ab(cd|cd)?ef/ => [%w[abef], %w[abcdef]],
|
167
|
+
/ab\\?cd/ => [%w[abcd], %w[ab\cd]]
|
96
168
|
)
|
97
169
|
end
|
98
170
|
|
@@ -152,5 +224,13 @@ RSpec.describe Capybara::Selector::RegexpDisassembler do
|
|
152
224
|
hsh.each do |regexp, expected|
|
153
225
|
expect(Capybara::Selector::RegexpDisassembler.new(regexp).substrings).to eq expected
|
154
226
|
end
|
227
|
+
verify_alternated_strings(hsh, wrap: true)
|
228
|
+
end
|
229
|
+
|
230
|
+
def verify_alternated_strings(hsh, wrap: false)
|
231
|
+
hsh.each do |regexp, expected|
|
232
|
+
expected = [expected] if wrap && (expected != [])
|
233
|
+
expect(Capybara::Selector::RegexpDisassembler.new(regexp).alternated_substrings).to eq expected
|
234
|
+
end
|
155
235
|
end
|
156
236
|
end
|
data/spec/selector_spec.rb
CHANGED
@@ -301,6 +301,9 @@ RSpec.describe Capybara do
|
|
301
301
|
describe ':id selector' do
|
302
302
|
it 'finds by locator' do
|
303
303
|
expect(string.find(:id, 'my_text_input')[:name]).to eq 'form[my_text_input]'
|
304
|
+
expect(string.find(:id, /my_text_input/)[:name]).to eq 'form[my_text_input]'
|
305
|
+
expect(string.find(:id, /_text_/)[:name]).to eq 'form[my_text_input]'
|
306
|
+
expect(string.find(:id, /i[nmo]/)[:name]).to eq 'form[my_text_input]'
|
304
307
|
end
|
305
308
|
end
|
306
309
|
|
@@ -5,29 +5,23 @@ require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
6
6
|
require 'rspec/shared_spec_matchers'
|
7
7
|
|
8
|
-
CHROME_DRIVER =
|
8
|
+
CHROME_DRIVER = :selenium_chrome
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
driver
|
14
|
-
end
|
10
|
+
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
11
|
+
browser_options.headless! if ENV['HEADLESS']
|
12
|
+
browser_options.add_option(:w3c, !!ENV['W3C'])
|
15
13
|
|
16
|
-
Capybara.register_driver :
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
21
|
-
driver.browser.download_path = Capybara.save_path
|
22
|
-
driver
|
14
|
+
Capybara.register_driver :selenium_chrome do |app|
|
15
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options).tap do |driver|
|
16
|
+
driver.browser.download_path = Capybara.save_path
|
17
|
+
end
|
23
18
|
end
|
24
19
|
|
25
20
|
Capybara.register_driver :selenium_chrome_clear_storage do |app|
|
26
21
|
chrome_options = {
|
27
22
|
browser: :chrome,
|
28
|
-
options:
|
23
|
+
options: browser_options
|
29
24
|
}
|
30
|
-
chrome_options[:options].headless! if ENV['HEADLESS']
|
31
25
|
Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: true, clear_session_storage: true))
|
32
26
|
end
|
33
27
|
|
@@ -38,11 +38,12 @@ Capybara.register_driver :selenium_chrome_remote do |app|
|
|
38
38
|
ensure_selenium_running!
|
39
39
|
|
40
40
|
url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
|
41
|
-
|
41
|
+
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
42
42
|
|
43
43
|
Capybara::Selenium::Driver.new app,
|
44
44
|
browser: :remote,
|
45
|
-
desired_capabilities:
|
45
|
+
desired_capabilities: :chrome,
|
46
|
+
options: browser_options,
|
46
47
|
url: url
|
47
48
|
end
|
48
49
|
|
@@ -34,11 +34,12 @@ Capybara.register_driver :selenium_firefox_remote do |app|
|
|
34
34
|
ensure_selenium_running!
|
35
35
|
|
36
36
|
url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
|
37
|
-
|
37
|
+
browser_options = ::Selenium::WebDriver::Firefox::Options.new
|
38
38
|
|
39
39
|
Capybara::Selenium::Driver.new app,
|
40
40
|
browser: :remote,
|
41
|
-
desired_capabilities:
|
41
|
+
desired_capabilities: :firefox,
|
42
|
+
options: browser_options,
|
42
43
|
url: url
|
43
44
|
end
|
44
45
|
|
@@ -71,6 +72,9 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE
|
|
71
72
|
pending "FF < 62 doesn't support setting all files at once" if marionette_lt?(62, @session)
|
72
73
|
when 'Capybara::Session selenium_firefox_remote #reset_session! removes ALL cookies'
|
73
74
|
pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
|
75
|
+
when /#accept_confirm should work with nested modals$/
|
76
|
+
# skip because this is timing based and hence flaky when set to pending
|
77
|
+
skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if marionette_gte?(63, @session)
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Walpole
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain:
|
12
12
|
- gem-public_cert.pem
|
13
|
-
date: 2018-11-
|
13
|
+
date: 2018-11-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -110,6 +110,20 @@ dependencies:
|
|
110
110
|
- - "~>"
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '3.2'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: byebug
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
113
127
|
- !ruby/object:Gem::Dependency
|
114
128
|
name: cucumber
|
115
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,6 +236,34 @@ dependencies:
|
|
222
236
|
- - ">="
|
223
237
|
- !ruby/object:Gem::Version
|
224
238
|
version: 3.4.0
|
239
|
+
- !ruby/object:Gem::Dependency
|
240
|
+
name: rubocop
|
241
|
+
requirement: !ruby/object:Gem::Requirement
|
242
|
+
requirements:
|
243
|
+
- - ">="
|
244
|
+
- !ruby/object:Gem::Version
|
245
|
+
version: '0'
|
246
|
+
type: :development
|
247
|
+
prerelease: false
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
249
|
+
requirements:
|
250
|
+
- - ">="
|
251
|
+
- !ruby/object:Gem::Version
|
252
|
+
version: '0'
|
253
|
+
- !ruby/object:Gem::Dependency
|
254
|
+
name: rubocop-rspec
|
255
|
+
requirement: !ruby/object:Gem::Requirement
|
256
|
+
requirements:
|
257
|
+
- - ">="
|
258
|
+
- !ruby/object:Gem::Version
|
259
|
+
version: '0'
|
260
|
+
type: :development
|
261
|
+
prerelease: false
|
262
|
+
version_requirements: !ruby/object:Gem::Requirement
|
263
|
+
requirements:
|
264
|
+
- - ">="
|
265
|
+
- !ruby/object:Gem::Version
|
266
|
+
version: '0'
|
225
267
|
- !ruby/object:Gem::Dependency
|
226
268
|
name: selenium-webdriver
|
227
269
|
requirement: !ruby/object:Gem::Requirement
|
@@ -310,10 +352,18 @@ files:
|
|
310
352
|
- lib/capybara/rails.rb
|
311
353
|
- lib/capybara/result.rb
|
312
354
|
- lib/capybara/rspec.rb
|
313
|
-
- lib/capybara/rspec/compound.rb
|
314
355
|
- lib/capybara/rspec/features.rb
|
315
356
|
- lib/capybara/rspec/matcher_proxies.rb
|
316
357
|
- lib/capybara/rspec/matchers.rb
|
358
|
+
- lib/capybara/rspec/matchers/base.rb
|
359
|
+
- lib/capybara/rspec/matchers/become_closed.rb
|
360
|
+
- lib/capybara/rspec/matchers/compound.rb
|
361
|
+
- lib/capybara/rspec/matchers/have_current_path.rb
|
362
|
+
- lib/capybara/rspec/matchers/have_selector.rb
|
363
|
+
- lib/capybara/rspec/matchers/have_style.rb
|
364
|
+
- lib/capybara/rspec/matchers/have_text.rb
|
365
|
+
- lib/capybara/rspec/matchers/have_title.rb
|
366
|
+
- lib/capybara/rspec/matchers/match_selector.rb
|
317
367
|
- lib/capybara/selector.rb
|
318
368
|
- lib/capybara/selector/builders/css_builder.rb
|
319
369
|
- lib/capybara/selector/builders/xpath_builder.rb
|
@@ -446,6 +496,7 @@ files:
|
|
446
496
|
- lib/capybara/spec/views/header_links.erb
|
447
497
|
- lib/capybara/spec/views/host_links.erb
|
448
498
|
- lib/capybara/spec/views/initial_alert.erb
|
499
|
+
- lib/capybara/spec/views/obscured.erb
|
449
500
|
- lib/capybara/spec/views/path.erb
|
450
501
|
- lib/capybara/spec/views/popup_one.erb
|
451
502
|
- lib/capybara/spec/views/popup_two.erb
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
if defined?(::RSpec::Expectations::Version)
|
4
|
-
module Capybara
|
5
|
-
module RSpecMatchers
|
6
|
-
module Compound
|
7
|
-
include ::RSpec::Matchers::Composable
|
8
|
-
|
9
|
-
def and(matcher)
|
10
|
-
And.new(self, matcher)
|
11
|
-
end
|
12
|
-
|
13
|
-
def and_then(matcher)
|
14
|
-
::RSpec::Matchers::BuiltIn::Compound::And.new(self, matcher)
|
15
|
-
end
|
16
|
-
|
17
|
-
def or(matcher)
|
18
|
-
Or.new(self, matcher)
|
19
|
-
end
|
20
|
-
|
21
|
-
class CapybaraEvaluator
|
22
|
-
def initialize(actual)
|
23
|
-
@actual = actual
|
24
|
-
@match_results = Hash.new { |hsh, matcher| hsh[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
|
34
|
-
end
|
35
|
-
|
36
|
-
# @api private
|
37
|
-
module Synchronizer
|
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 synchronized_match?
|
45
|
-
|
46
|
-
true
|
47
|
-
end
|
48
|
-
rescue StandardError
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
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
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class And < ::RSpec::Matchers::BuiltIn::Compound::And
|
65
|
-
include Synchronizer
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def synchronized_match?
|
70
|
-
[matcher_1_matches?, matcher_2_matches?].all?
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class Or < ::RSpec::Matchers::BuiltIn::Compound::Or
|
75
|
-
include Synchronizer
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def synchronized_match?
|
80
|
-
[matcher_1_matches?, matcher_2_matches?].any?
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|