capybara 3.29.0 → 3.30.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 +19 -1
- data/README.md +1 -1
- data/lib/capybara/config.rb +7 -3
- data/lib/capybara/helpers.rb +3 -1
- data/lib/capybara/node/actions.rb +23 -19
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +10 -8
- data/lib/capybara/node/finders.rb +12 -10
- data/lib/capybara/node/matchers.rb +39 -33
- data/lib/capybara/node/simple.rb +3 -1
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +17 -4
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +4 -1
- data/lib/capybara/rack_test/driver.rb +1 -1
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/selector.rb +22 -16
- data/lib/capybara/selector/css.rb +1 -1
- data/lib/capybara/selector/definition.rb +2 -2
- data/lib/capybara/selector/definition/button.rb +7 -2
- data/lib/capybara/selector/definition/checkbox.rb +2 -2
- data/lib/capybara/selector/definition/css.rb +3 -1
- data/lib/capybara/selector/definition/datalist_input.rb +1 -1
- data/lib/capybara/selector/definition/datalist_option.rb +1 -1
- data/lib/capybara/selector/definition/element.rb +1 -1
- data/lib/capybara/selector/definition/field.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/label.rb +3 -1
- data/lib/capybara/selector/definition/radio_button.rb +2 -2
- data/lib/capybara/selector/definition/select.rb +1 -1
- data/lib/capybara/selector/definition/table.rb +5 -2
- data/lib/capybara/selector/filter_set.rb +11 -9
- data/lib/capybara/selector/filters/base.rb +6 -1
- data/lib/capybara/selector/filters/locator_filter.rb +1 -1
- data/lib/capybara/selector/selector.rb +4 -2
- data/lib/capybara/selenium/driver.rb +19 -11
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -2
- data/lib/capybara/selenium/extensions/html5_drag.rb +6 -5
- data/lib/capybara/selenium/node.rb +6 -4
- data/lib/capybara/selenium/nodes/chrome_node.rb +7 -3
- data/lib/capybara/selenium/nodes/edge_node.rb +3 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/server.rb +15 -3
- data/lib/capybara/server/checker.rb +1 -1
- data/lib/capybara/server/middleware.rb +20 -10
- data/lib/capybara/session.rb +10 -8
- data/lib/capybara/session/config.rb +6 -2
- data/lib/capybara/session/matchers.rb +6 -6
- data/lib/capybara/spec/public/test.js +11 -0
- data/lib/capybara/spec/session/all_spec.rb +15 -0
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +4 -0
- data/lib/capybara/spec/session/click_button_spec.rb +5 -0
- data/lib/capybara/spec/session/find_spec.rb +20 -0
- data/lib/capybara/spec/session/has_table_spec.rb +51 -5
- data/lib/capybara/spec/session/has_text_spec.rb +31 -0
- data/lib/capybara/spec/session/node_spec.rb +15 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
- data/lib/capybara/spec/session/selectors_spec.rb +15 -2
- data/lib/capybara/spec/views/form.erb +5 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/dsl_spec.rb +2 -2
- data/spec/minitest_spec_spec.rb +46 -46
- data/spec/regexp_dissassembler_spec.rb +45 -37
- data/spec/result_spec.rb +3 -3
- data/spec/rspec/features_spec.rb +1 -0
- data/spec/rspec/shared_spec_matchers.rb +3 -3
- data/spec/rspec_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +3 -3
- data/spec/selenium_spec_firefox.rb +7 -2
- data/spec/server_spec.rb +42 -0
- data/spec/session_spec.rb +1 -1
- data/spec/shared_selenium_node.rb +3 -3
- data/spec/shared_selenium_session.rb +8 -7
- metadata +3 -3
@@ -79,14 +79,18 @@ module Capybara
|
|
79
79
|
|
80
80
|
remove_method :app_host=
|
81
81
|
def app_host=(url)
|
82
|
-
|
82
|
+
unless url.nil? || url.match?(URI::DEFAULT_PARSER.make_regexp)
|
83
|
+
raise ArgumentError, "Capybara.app_host should be set to a url (http://www.example.com). Attempted to set #{url.inspect}."
|
84
|
+
end
|
83
85
|
|
84
86
|
@app_host = url
|
85
87
|
end
|
86
88
|
|
87
89
|
remove_method :default_host=
|
88
90
|
def default_host=(url)
|
89
|
-
|
91
|
+
unless url.nil? || url.match?(URI::DEFAULT_PARSER.make_regexp)
|
92
|
+
raise ArgumentError, "Capybara.default_host should be set to a url (http://www.example.com). Attempted to set #{url.inspect}."
|
93
|
+
end
|
90
94
|
|
91
95
|
@default_host = url
|
92
96
|
end
|
@@ -20,7 +20,7 @@ module Capybara
|
|
20
20
|
# @return [true]
|
21
21
|
#
|
22
22
|
def assert_current_path(path, **options)
|
23
|
-
_verify_current_path(path, options) do |query|
|
23
|
+
_verify_current_path(path, **options) do |query|
|
24
24
|
raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
|
25
25
|
end
|
26
26
|
end
|
@@ -36,7 +36,7 @@ module Capybara
|
|
36
36
|
# @return [true]
|
37
37
|
#
|
38
38
|
def assert_no_current_path(path, **options)
|
39
|
-
_verify_current_path(path, options) do |query|
|
39
|
+
_verify_current_path(path, **options) do |query|
|
40
40
|
raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self)
|
41
41
|
end
|
42
42
|
end
|
@@ -51,7 +51,7 @@ module Capybara
|
|
51
51
|
# @return [Boolean]
|
52
52
|
#
|
53
53
|
def has_current_path?(path, **options)
|
54
|
-
make_predicate(options) { assert_current_path(path, options) }
|
54
|
+
make_predicate(options) { assert_current_path(path, **options) }
|
55
55
|
end
|
56
56
|
|
57
57
|
##
|
@@ -64,13 +64,13 @@ module Capybara
|
|
64
64
|
# @return [Boolean]
|
65
65
|
#
|
66
66
|
def has_no_current_path?(path, **options)
|
67
|
-
make_predicate(options) { assert_no_current_path(path, options) }
|
67
|
+
make_predicate(options) { assert_no_current_path(path, **options) }
|
68
68
|
end
|
69
69
|
|
70
70
|
private
|
71
71
|
|
72
|
-
def _verify_current_path(path, options)
|
73
|
-
query = Capybara::Queries::CurrentPathQuery.new(path, options)
|
72
|
+
def _verify_current_path(path, **options)
|
73
|
+
query = Capybara::Queries::CurrentPathQuery.new(path, **options)
|
74
74
|
document.synchronize(query.wait) do
|
75
75
|
yield(query)
|
76
76
|
end
|
@@ -12,10 +12,21 @@ $(function() {
|
|
12
12
|
$('#drag_html5, #drag_html5_scroll').on('dragstart', function(ev){
|
13
13
|
ev.originalEvent.dataTransfer.setData("text", ev.target.id);
|
14
14
|
});
|
15
|
+
$('#drag_html5, #drag_html5_scroll').on('dragend', function(ev){
|
16
|
+
$(this).after('<div class="log">DragEnd with client position: ' + ev.clientX + ',' + ev.clientY)
|
17
|
+
});
|
15
18
|
$('#drop_html5, #drop_html5_scroll').on('dragover', function(ev){
|
16
19
|
$(this).after('<div class="log">DragOver with client position: ' + ev.clientX + ',' + ev.clientY)
|
17
20
|
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
18
21
|
});
|
22
|
+
$('#drop_html5, #drop_html5_scroll').on('dragleave', function(ev){
|
23
|
+
$(this).after('<div class="log">DragLeave with client position: ' + ev.clientX + ',' + ev.clientY)
|
24
|
+
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
25
|
+
});
|
26
|
+
$('#drop_html5, #drop_html5_scroll').on('drop', function(ev){
|
27
|
+
$(this).after('<div class="log">Drop with client position: ' + ev.clientX + ',' + ev.clientY)
|
28
|
+
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
29
|
+
});
|
19
30
|
$('#drop_html5, #drop_html5_scroll').on('drop', function(ev){
|
20
31
|
ev.preventDefault();
|
21
32
|
var oev = ev.originalEvent;
|
@@ -36,6 +36,13 @@ Capybara::SpecHelper.spec '#all' do
|
|
36
36
|
expect(@result).to include('Smith', 'John', 'John Smith')
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'should allow reversing the order' do
|
40
|
+
@session.visit('/form')
|
41
|
+
fields = @session.all(:fillable_field, 'Name', exact: false).to_a
|
42
|
+
reverse_fields = @session.all(:fillable_field, 'Name', order: :reverse, exact: false).to_a
|
43
|
+
expect(fields).to eq(reverse_fields.reverse)
|
44
|
+
end
|
45
|
+
|
39
46
|
it 'should raise an error when given invalid options' do
|
40
47
|
expect { @session.all('//p', schmoo: 'foo') }.to raise_error(ArgumentError)
|
41
48
|
end
|
@@ -128,6 +135,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
128
135
|
it 'should succeed when the number of elements founds matches the expectation' do
|
129
136
|
expect { @session.all(:css, 'h1, p', count: 4) }.not_to raise_error
|
130
137
|
end
|
138
|
+
|
131
139
|
it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do
|
132
140
|
expect { @session.all(:css, 'h1, p', count: 5) }.to raise_error(Capybara::ExpectationNotMet)
|
133
141
|
end
|
@@ -137,6 +145,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
137
145
|
it 'should succeed when the number of elements founds matches the expectation' do
|
138
146
|
expect { @session.all(:css, 'h1, p', minimum: 0) }.not_to raise_error
|
139
147
|
end
|
148
|
+
|
140
149
|
it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do
|
141
150
|
expect { @session.all(:css, 'h1, p', minimum: 5) }.to raise_error(Capybara::ExpectationNotMet)
|
142
151
|
end
|
@@ -146,6 +155,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
146
155
|
it 'should succeed when the number of elements founds matches the expectation' do
|
147
156
|
expect { @session.all(:css, 'h1, p', maximum: 4) }.not_to raise_error
|
148
157
|
end
|
158
|
+
|
149
159
|
it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do
|
150
160
|
expect { @session.all(:css, 'h1, p', maximum: 0) }.to raise_error(Capybara::ExpectationNotMet)
|
151
161
|
end
|
@@ -155,6 +165,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
155
165
|
it 'should succeed when the number of elements founds matches the expectation' do
|
156
166
|
expect { @session.all(:css, 'h1, p', between: 2..7) }.not_to raise_error
|
157
167
|
end
|
168
|
+
|
158
169
|
it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do
|
159
170
|
expect { @session.all(:css, 'h1, p', between: 0..3) }.to raise_error(Capybara::ExpectationNotMet)
|
160
171
|
end
|
@@ -175,6 +186,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
175
186
|
between: 0..3 }
|
176
187
|
expect { @session.all(:css, 'h1, p', o) }.not_to raise_error
|
177
188
|
end
|
189
|
+
|
178
190
|
context 'with no :count expectation' do
|
179
191
|
it 'fails if :minimum is not met' do
|
180
192
|
o = { minimum: 5,
|
@@ -182,18 +194,21 @@ Capybara::SpecHelper.spec '#all' do
|
|
182
194
|
between: 2..7 }
|
183
195
|
expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet)
|
184
196
|
end
|
197
|
+
|
185
198
|
it 'fails if :maximum is not met' do
|
186
199
|
o = { minimum: 0,
|
187
200
|
maximum: 0,
|
188
201
|
between: 2..7 }
|
189
202
|
expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet)
|
190
203
|
end
|
204
|
+
|
191
205
|
it 'fails if :between is not met' do
|
192
206
|
o = { minimum: 0,
|
193
207
|
maximum: 4,
|
194
208
|
between: 0..3 }
|
195
209
|
expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet)
|
196
210
|
end
|
211
|
+
|
197
212
|
it 'succeeds if all combineable expectations are met' do
|
198
213
|
o = { minimum: 0,
|
199
214
|
maximum: 4,
|
@@ -20,6 +20,11 @@ Capybara::SpecHelper.spec '#ancestor' do
|
|
20
20
|
expect(el.ancestor('//div', text: "Ancestor\nAncestor\nAncestor")[:id]).to eq('ancestor3')
|
21
21
|
end
|
22
22
|
|
23
|
+
it 'should find the closest ancestor' do
|
24
|
+
el = @session.find(:css, '#child')
|
25
|
+
expect(el.ancestor('.//div', order: :reverse, match: :first)[:id]).to eq('ancestor1')
|
26
|
+
end
|
27
|
+
|
23
28
|
it 'should raise an error if there are multiple matches' do
|
24
29
|
el = @session.find(:css, '#child')
|
25
30
|
expect { el.ancestor('//div') }.to raise_error(Capybara::Ambiguous)
|
@@ -159,6 +159,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
159
159
|
between: 0..4 }
|
160
160
|
expect { @session.assert_text('Header', o) }.not_to raise_error
|
161
161
|
end
|
162
|
+
|
162
163
|
context 'with no :count expectation' do
|
163
164
|
it 'fails if :minimum is not met' do
|
164
165
|
o = { minimum: 6,
|
@@ -166,18 +167,21 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
166
167
|
between: 2..7 }
|
167
168
|
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
168
169
|
end
|
170
|
+
|
169
171
|
it 'fails if :maximum is not met' do
|
170
172
|
o = { minimum: 0,
|
171
173
|
maximum: 0,
|
172
174
|
between: 2..7 }
|
173
175
|
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
174
176
|
end
|
177
|
+
|
175
178
|
it 'fails if :between is not met' do
|
176
179
|
o = { minimum: 0,
|
177
180
|
maximum: 5,
|
178
181
|
between: 0..4 }
|
179
182
|
expect { @session.assert_text('Header', o) }.to raise_error(Capybara::ExpectationNotMet)
|
180
183
|
end
|
184
|
+
|
181
185
|
it 'succeeds if all combineable expectations are met' do
|
182
186
|
o = { minimum: 0,
|
183
187
|
maximum: 5,
|
@@ -186,6 +186,11 @@ Capybara::SpecHelper.spec '#click_button' do
|
|
186
186
|
@session.click_button(name: 'form[awesome]')
|
187
187
|
expect(extract_results(@session)['first_name']).to eq('John')
|
188
188
|
end
|
189
|
+
|
190
|
+
it 'should submit by specific button name regex' do
|
191
|
+
@session.click_button(name: /form\[awes.*\]/)
|
192
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
193
|
+
end
|
189
194
|
end
|
190
195
|
|
191
196
|
context 'with fields associated with the form using the form attribute', requires: [:form_attribute] do
|
@@ -275,14 +275,17 @@ Capybara::SpecHelper.spec '#find' do
|
|
275
275
|
@session.find(:css, '.multiple', match: :one)
|
276
276
|
end.to raise_error(Capybara::Ambiguous)
|
277
277
|
end
|
278
|
+
|
278
279
|
it 'raises an error even if there the match is exact and the others are inexact' do
|
279
280
|
expect do
|
280
281
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], exact: false, match: :one)
|
281
282
|
end.to raise_error(Capybara::Ambiguous)
|
282
283
|
end
|
284
|
+
|
283
285
|
it 'returns the element if there is only one' do
|
284
286
|
expect(@session.find(:css, '.singular', match: :one).text).to eq('singular')
|
285
287
|
end
|
288
|
+
|
286
289
|
it 'raises an error if there is no match' do
|
287
290
|
expect do
|
288
291
|
@session.find(:css, '.does-not-exist', match: :one)
|
@@ -294,6 +297,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
294
297
|
it 'returns the first matched element' do
|
295
298
|
expect(@session.find(:css, '.multiple', match: :first).text).to eq('multiple one')
|
296
299
|
end
|
300
|
+
|
297
301
|
it 'raises an error if there is no match' do
|
298
302
|
expect do
|
299
303
|
@session.find(:css, '.does-not-exist', match: :first)
|
@@ -308,19 +312,23 @@ Capybara::SpecHelper.spec '#find' do
|
|
308
312
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: false)
|
309
313
|
end.to raise_error(Capybara::Ambiguous)
|
310
314
|
end
|
315
|
+
|
311
316
|
it 'finds a single exact match when there also are inexact matches' do
|
312
317
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: false)
|
313
318
|
expect(result.text).to eq('almost singular')
|
314
319
|
end
|
320
|
+
|
315
321
|
it 'raises an error when there are multiple inexact matches' do
|
316
322
|
expect do
|
317
323
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: false)
|
318
324
|
end.to raise_error(Capybara::Ambiguous)
|
319
325
|
end
|
326
|
+
|
320
327
|
it 'finds a single inexact match' do
|
321
328
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: false)
|
322
329
|
expect(result.text).to eq('almost singular but not quite')
|
323
330
|
end
|
331
|
+
|
324
332
|
it 'raises an error if there is no match' do
|
325
333
|
expect do
|
326
334
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: false)
|
@@ -334,20 +342,24 @@ Capybara::SpecHelper.spec '#find' do
|
|
334
342
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :smart, exact: true)
|
335
343
|
end.to raise_error(Capybara::Ambiguous)
|
336
344
|
end
|
345
|
+
|
337
346
|
it 'finds a single exact match when there also are inexact matches' do
|
338
347
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :smart, exact: true)
|
339
348
|
expect(result.text).to eq('almost singular')
|
340
349
|
end
|
350
|
+
|
341
351
|
it 'raises an error when there are multiple inexact matches' do
|
342
352
|
expect do
|
343
353
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :smart, exact: true)
|
344
354
|
end.to raise_error(Capybara::ElementNotFound)
|
345
355
|
end
|
356
|
+
|
346
357
|
it 'raises an error when there is a single inexact matches' do
|
347
358
|
expect do
|
348
359
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :smart, exact: true)
|
349
360
|
end.to raise_error(Capybara::ElementNotFound)
|
350
361
|
end
|
362
|
+
|
351
363
|
it 'raises an error if there is no match' do
|
352
364
|
expect do
|
353
365
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :smart, exact: true)
|
@@ -362,18 +374,22 @@ Capybara::SpecHelper.spec '#find' do
|
|
362
374
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: false)
|
363
375
|
expect(result.text).to eq('multiple one')
|
364
376
|
end
|
377
|
+
|
365
378
|
it 'finds a single exact match when there also are inexact matches' do
|
366
379
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: false)
|
367
380
|
expect(result.text).to eq('almost singular')
|
368
381
|
end
|
382
|
+
|
369
383
|
it 'picks the first one when there are multiple inexact matches' do
|
370
384
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: false)
|
371
385
|
expect(result.text).to eq('almost singular but not quite')
|
372
386
|
end
|
387
|
+
|
373
388
|
it 'finds a single inexact match' do
|
374
389
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: false)
|
375
390
|
expect(result.text).to eq('almost singular but not quite')
|
376
391
|
end
|
392
|
+
|
377
393
|
it 'raises an error if there is no match' do
|
378
394
|
expect do
|
379
395
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: false)
|
@@ -386,20 +402,24 @@ Capybara::SpecHelper.spec '#find' do
|
|
386
402
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('multiple')], match: :prefer_exact, exact: true)
|
387
403
|
expect(result.text).to eq('multiple one')
|
388
404
|
end
|
405
|
+
|
389
406
|
it 'finds a single exact match when there also are inexact matches' do
|
390
407
|
result = @session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular')], match: :prefer_exact, exact: true)
|
391
408
|
expect(result.text).to eq('almost singular')
|
392
409
|
end
|
410
|
+
|
393
411
|
it 'raises an error if there are multiple inexact matches' do
|
394
412
|
expect do
|
395
413
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singul')], match: :prefer_exact, exact: true)
|
396
414
|
end.to raise_error(Capybara::ElementNotFound)
|
397
415
|
end
|
416
|
+
|
398
417
|
it 'raises an error if there is a single inexact match' do
|
399
418
|
expect do
|
400
419
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('almost_singular but')], match: :prefer_exact, exact: true)
|
401
420
|
end.to raise_error(Capybara::ElementNotFound)
|
402
421
|
end
|
422
|
+
|
403
423
|
it 'raises an error if there is no match' do
|
404
424
|
expect do
|
405
425
|
@session.find(:xpath, XPath.descendant[XPath.attr(:class).is('does-not-exist')], match: :prefer_exact, exact: true)
|
@@ -143,10 +143,56 @@ Capybara::SpecHelper.spec '#has_no_table?' do
|
|
143
143
|
])
|
144
144
|
end
|
145
145
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
146
|
+
context 'using :with_cols' do
|
147
|
+
it 'should consider a single column' do
|
148
|
+
expect(@session).to have_no_table('Vertical Headers', with_cols:
|
149
|
+
[
|
150
|
+
{ 'First Name' => 'Joe' }
|
151
|
+
])
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should be true even if the last column does exist' do
|
155
|
+
expect(@session).to have_no_table('Vertical Headers', with_cols:
|
156
|
+
[
|
157
|
+
{
|
158
|
+
'First Name' => 'What?',
|
159
|
+
'What?' => 'Walpole',
|
160
|
+
'City' => 'Oceanside' # This line makes the example fail
|
161
|
+
}
|
162
|
+
])
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should be true if none of the columns exist' do
|
166
|
+
expect(@session).to have_no_table('Vertical Headers', with_cols:
|
167
|
+
[
|
168
|
+
{
|
169
|
+
'First Name' => 'What?',
|
170
|
+
'What?' => 'Walpole',
|
171
|
+
'City' => 'What?'
|
172
|
+
}
|
173
|
+
])
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should be true if the first column does match' do
|
177
|
+
expect(@session).to have_no_table('Vertical Headers', with_cols:
|
178
|
+
[
|
179
|
+
{
|
180
|
+
'First Name' => 'Thomas',
|
181
|
+
'Last Name' => 'What',
|
182
|
+
'City' => 'What'
|
183
|
+
}
|
184
|
+
])
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should be true if none of the columns match' do
|
188
|
+
expect(@session).to have_no_table('Vertical Headers', with_cols:
|
189
|
+
[
|
190
|
+
{
|
191
|
+
'First Name' => 'What',
|
192
|
+
'Last Name' => 'What',
|
193
|
+
'City' => 'What'
|
194
|
+
}
|
195
|
+
])
|
196
|
+
end
|
151
197
|
end
|
152
198
|
end
|
@@ -111,6 +111,37 @@ Capybara::SpecHelper.spec '#has_text?' do
|
|
111
111
|
expect(@session).not_to have_text(/xxxxyzzz/)
|
112
112
|
end
|
113
113
|
|
114
|
+
context 'with object implementing to_s and to_hash' do
|
115
|
+
it 'should work if the object is passed alone' do
|
116
|
+
with_to_hash = Class.new do
|
117
|
+
def to_s; '42' end
|
118
|
+
def to_hash; { value: 'Other hash' } end
|
119
|
+
end.new
|
120
|
+
@session.visit('/with_html')
|
121
|
+
expect(@session).to have_text(with_to_hash)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should work if passed with empty options' do
|
125
|
+
with_to_hash = Class.new do
|
126
|
+
def to_s; '42' end
|
127
|
+
def to_hash; { value: 'Other hash' } end
|
128
|
+
end.new
|
129
|
+
@session.visit('/with_html')
|
130
|
+
expect(@session).to have_text(:visible, with_to_hash, {})
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should fail if passed without empty options' do
|
134
|
+
with_to_hash = Class.new do
|
135
|
+
def to_s; '42' end
|
136
|
+
def to_hash; { blah: 'Other hash' } end
|
137
|
+
end.new
|
138
|
+
@session.visit('/with_html')
|
139
|
+
expect do
|
140
|
+
expect(@session).to have_text(:visible, with_to_hash)
|
141
|
+
end.to raise_error(ArgumentError)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
114
145
|
context 'with exact: true option' do
|
115
146
|
it 'should be true if text matches exactly' do
|
116
147
|
@session.visit('/with_html')
|
@@ -493,6 +493,21 @@ Capybara::SpecHelper.spec 'node' do
|
|
493
493
|
expect(@session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
|
494
494
|
end
|
495
495
|
|
496
|
+
it 'should preserve clientX/Y from last dragover event' do
|
497
|
+
@session.visit('/with_js')
|
498
|
+
element = @session.find('//div[@id="drag_html5"]')
|
499
|
+
target = @session.find('//div[@id="drop_html5"]')
|
500
|
+
element.drag_to(target)
|
501
|
+
|
502
|
+
# The first "DragOver" div is inserted by the last dragover event dispatched
|
503
|
+
drag_over_div = @session.find('//div[@class="log" and starts-with(text(), "DragOver")]', match: :first)
|
504
|
+
position = drag_over_div.text.sub('DragOver ', '')
|
505
|
+
|
506
|
+
expect(@session).to have_css('div.log', text: /DragLeave #{position}/, count: 1)
|
507
|
+
expect(@session).to have_css('div.log', text: /Drop #{position}/, count: 1)
|
508
|
+
expect(@session).to have_css('div.log', text: /DragEnd #{position}/, count: 1)
|
509
|
+
end
|
510
|
+
|
496
511
|
it 'should not HTML5 drag and drop on a non HTML5 drop element' do
|
497
512
|
@session.visit('/with_js')
|
498
513
|
element = @session.find('//div[@id="drag_html5"]')
|