capybara 3.19.0 → 3.20.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.
- checksums.yaml +4 -4
- data/History.md +27 -2
- data/README.md +1 -1
- data/lib/capybara/driver/node.rb +4 -0
- data/lib/capybara/node/actions.rb +3 -2
- data/lib/capybara/node/element.rb +11 -0
- data/lib/capybara/node/finders.rb +4 -1
- data/lib/capybara/queries/selector_query.rb +19 -5
- data/lib/capybara/selector/definition/label.rb +27 -10
- data/lib/capybara/selector/definition/link.rb +3 -2
- data/lib/capybara/selector.rb +2 -2
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +15 -2
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +1 -1
- data/lib/capybara/selenium/node.rb +25 -1
- data/lib/capybara/selenium/nodes/safari_node.rb +19 -6
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/spec/session/all_spec.rb +23 -0
- data/lib/capybara/spec/session/click_link_spec.rb +11 -0
- data/lib/capybara/spec/session/node_spec.rb +78 -5
- data/lib/capybara/spec/session/selectors_spec.rb +8 -0
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/frame_one.erb +1 -0
- data/lib/capybara/spec/views/obscured.erb +9 -9
- data/lib/capybara/version.rb +1 -1
- data/spec/sauce_spec_chrome.rb +1 -0
- data/spec/selenium_spec_chrome.rb +17 -2
- data/spec/selenium_spec_chrome_remote.rb +4 -2
- data/spec/selenium_spec_edge.rb +4 -2
- data/spec/selenium_spec_firefox.rb +4 -11
- data/spec/selenium_spec_firefox_remote.rb +4 -2
- data/spec/selenium_spec_ie.rb +5 -6
- data/spec/selenium_spec_safari.rb +7 -12
- data/spec/server_spec.rb +4 -2
- data/spec/shared_selenium_node.rb +29 -0
- metadata +23 -2
|
@@ -118,6 +118,17 @@ Capybara::SpecHelper.spec '#click_link' do
|
|
|
118
118
|
expect { @session.click_link('Normal Anchor', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
|
+
|
|
122
|
+
context 'href: false' do
|
|
123
|
+
it 'should not raise an error on links with no href attribute' do
|
|
124
|
+
expect { @session.click_link('No Href', href: false) }.not_to raise_error
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'should not raise an error if href attribute exists' do
|
|
128
|
+
expect { @session.click_link('Blank Href', href: false) }.not_to raise_error
|
|
129
|
+
expect { @session.click_link('Normal Anchor', href: false) }.not_to raise_error
|
|
130
|
+
end
|
|
131
|
+
end
|
|
121
132
|
end
|
|
122
133
|
|
|
123
134
|
it 'should follow relative links' do
|
|
@@ -251,6 +251,79 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
251
251
|
end
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
+
describe '#obscured?', requires: [:css] do
|
|
255
|
+
it 'should see non visible elements as obscured' do
|
|
256
|
+
Capybara.ignore_hidden_elements = false
|
|
257
|
+
expect(@session.find('//div[@id="hidden"]')).to be_obscured
|
|
258
|
+
expect(@session.find('//div[@id="hidden_via_ancestor"]')).to be_obscured
|
|
259
|
+
expect(@session.find('//div[@id="hidden_attr"]')).to be_obscured
|
|
260
|
+
expect(@session.find('//a[@id="hidden_attr_via_ancestor"]')).to be_obscured
|
|
261
|
+
expect(@session.find('//input[@id="hidden_input"]')).to be_obscured
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'should see non-overlapped elements as not obscured' do
|
|
265
|
+
@session.visit('/obscured')
|
|
266
|
+
expect(@session.find(:css, '#cover')).not_to be_obscured
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it 'should see elements only overlapped by descendants as not obscured' do
|
|
270
|
+
expect(@session.first(:css, 'p:not(.para)')).not_to be_obscured
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'should see elements outside the viewport as obscured' do
|
|
274
|
+
@session.visit('/obscured')
|
|
275
|
+
off = @session.find(:css, '#offscreen')
|
|
276
|
+
off_wrapper = @session.find(:css, '#offscreen_wrapper')
|
|
277
|
+
expect(off).to be_obscured
|
|
278
|
+
expect(off_wrapper).to be_obscured
|
|
279
|
+
@session.scroll_to(off_wrapper)
|
|
280
|
+
expect(off_wrapper).not_to be_obscured
|
|
281
|
+
expect(off).to be_obscured
|
|
282
|
+
off_wrapper.scroll_to(off)
|
|
283
|
+
expect(off).not_to be_obscured
|
|
284
|
+
expect(off_wrapper).not_to be_obscured
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it 'should see overlapped elements as obscured' do
|
|
288
|
+
@session.visit('/obscured')
|
|
289
|
+
expect(@session.find(:css, '#obscured')).to be_obscured
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it 'should be boolean' do
|
|
293
|
+
Capybara.ignore_hidden_elements = false
|
|
294
|
+
expect(@session.first('//a').obscured?).to be false
|
|
295
|
+
expect(@session.find('//div[@id="hidden"]').obscured?).to be true
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it 'should work in frames' do
|
|
299
|
+
@session.visit('/obscured')
|
|
300
|
+
frame = @session.find(:css, '#frameOne')
|
|
301
|
+
@session.within_frame(frame) do
|
|
302
|
+
div = @session.find(:css, '#divInFrameOne')
|
|
303
|
+
expect(div).to be_obscured
|
|
304
|
+
@session.scroll_to div
|
|
305
|
+
expect(div).not_to be_obscured
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it 'should work in nested iframes' do
|
|
310
|
+
@session.visit('/obscured')
|
|
311
|
+
frame = @session.find(:css, '#nestedFrames')
|
|
312
|
+
@session.within_frame(frame) do
|
|
313
|
+
@session.within_frame(:css, '#childFrame') do
|
|
314
|
+
gcframe = @session.find(:css, '#grandchildFrame2')
|
|
315
|
+
@session.within_frame(gcframe) do
|
|
316
|
+
expect(@session.find(:css, '#divInFrameTwo')).to be_obscured
|
|
317
|
+
end
|
|
318
|
+
@session.scroll_to(gcframe)
|
|
319
|
+
@session.within_frame(gcframe) do
|
|
320
|
+
expect(@session.find(:css, '#divInFrameTwo')).not_to be_obscured
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
254
327
|
describe '#checked?' do
|
|
255
328
|
it 'should extract node checked state' do
|
|
256
329
|
@session.visit('/form')
|
|
@@ -441,7 +514,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
441
514
|
end
|
|
442
515
|
|
|
443
516
|
it 'should retry clicking', requires: [:js] do
|
|
444
|
-
@session.visit('/
|
|
517
|
+
@session.visit('/animated')
|
|
445
518
|
obscured = @session.find(:css, '#obscured')
|
|
446
519
|
@session.execute_script <<~JS
|
|
447
520
|
setTimeout(function(){ $('#cover').hide(); }, 700)
|
|
@@ -450,7 +523,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
450
523
|
end
|
|
451
524
|
|
|
452
525
|
it 'should allow to retry longer', requires: [:js] do
|
|
453
|
-
@session.visit('/
|
|
526
|
+
@session.visit('/animated')
|
|
454
527
|
obscured = @session.find(:css, '#obscured')
|
|
455
528
|
@session.execute_script <<~JS
|
|
456
529
|
setTimeout(function(){ $('#cover').hide(); }, 3000)
|
|
@@ -459,7 +532,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
459
532
|
end
|
|
460
533
|
|
|
461
534
|
it 'should not retry clicking when wait is disabled', requires: [:js] do
|
|
462
|
-
@session.visit('/
|
|
535
|
+
@session.visit('/animated')
|
|
463
536
|
obscured = @session.find(:css, '#obscured')
|
|
464
537
|
@session.execute_script <<~JS
|
|
465
538
|
setTimeout(function(){ $('#cover').hide(); }, 2000)
|
|
@@ -493,7 +566,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
493
566
|
end
|
|
494
567
|
|
|
495
568
|
it 'should retry clicking', requires: [:js] do
|
|
496
|
-
@session.visit('/
|
|
569
|
+
@session.visit('/animated')
|
|
497
570
|
obscured = @session.find(:css, '#obscured')
|
|
498
571
|
@session.execute_script <<~JS
|
|
499
572
|
setTimeout(function(){ $('#cover').hide(); }, 700)
|
|
@@ -527,7 +600,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
527
600
|
end
|
|
528
601
|
|
|
529
602
|
it 'should retry clicking', requires: [:js] do
|
|
530
|
-
@session.visit('/
|
|
603
|
+
@session.visit('/animated')
|
|
531
604
|
obscured = @session.find(:css, '#obscured')
|
|
532
605
|
@session.execute_script <<~JS
|
|
533
606
|
setTimeout(function(){ $('#cover').hide(); }, 700)
|
|
@@ -14,10 +14,18 @@ Capybara::SpecHelper.spec Capybara::Selector do
|
|
|
14
14
|
expect(@session.find(:label, for: 'form_other_title')['for']).to eq 'form_other_title'
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
it 'finds a label for for attribute regex' do
|
|
18
|
+
expect(@session.find(:label, for: /_other_title/)['for']).to eq 'form_other_title'
|
|
19
|
+
end
|
|
20
|
+
|
|
17
21
|
it 'finds a label from nested input using :for filter with id string' do
|
|
18
22
|
expect(@session.find(:label, for: 'nested_label').text).to eq 'Nested Label'
|
|
19
23
|
end
|
|
20
24
|
|
|
25
|
+
it 'finds a label from nested input using :for filter with id regexp' do
|
|
26
|
+
expect(@session.find(:label, for: /nested_lab/).text).to eq 'Nested Label'
|
|
27
|
+
end
|
|
28
|
+
|
|
21
29
|
it 'finds a label from nested input using :for filter with element' do
|
|
22
30
|
input = @session.find(:id, 'nested_label')
|
|
23
31
|
expect(@session.find(:label, for: input).text).to eq 'Nested Label'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
|
4
|
+
<title>with_animation</title>
|
|
5
|
+
<script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
|
|
6
|
+
<script>
|
|
7
|
+
$(document).on('contextmenu', function(e){ e.preventDefault(); });
|
|
8
|
+
</script>
|
|
9
|
+
<style>
|
|
10
|
+
div {
|
|
11
|
+
width: 400px;
|
|
12
|
+
height: 400px;
|
|
13
|
+
position: absolute;
|
|
14
|
+
}
|
|
15
|
+
#obscured {
|
|
16
|
+
z-index: 1;
|
|
17
|
+
background-color: red;
|
|
18
|
+
}
|
|
19
|
+
#cover {
|
|
20
|
+
z-index: 2;
|
|
21
|
+
background-color: blue;
|
|
22
|
+
}
|
|
23
|
+
#offscreen {
|
|
24
|
+
top: 2000px;
|
|
25
|
+
left: 2000px;
|
|
26
|
+
background-color: green;
|
|
27
|
+
}
|
|
28
|
+
#offscreen_wrapper {
|
|
29
|
+
top: 2000px;
|
|
30
|
+
left: 2000px;
|
|
31
|
+
overflow-x: scroll;
|
|
32
|
+
background-color: yellow;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
|
|
37
|
+
<body id="with_animation">
|
|
38
|
+
<div id="obscured">
|
|
39
|
+
<input id="obscured_input"/>
|
|
40
|
+
</div>
|
|
41
|
+
<div id="cover"></div>
|
|
42
|
+
<div id="offscreen_wrapper">
|
|
43
|
+
<div id="offscreen"></div>
|
|
44
|
+
</div>
|
|
45
|
+
</body>
|
|
46
|
+
|
|
47
|
+
<iframe id="frameOne" src="/frame_one"></iframe>
|
|
48
|
+
</html>
|
|
49
|
+
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
<html>
|
|
2
2
|
<head>
|
|
3
3
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
|
4
|
-
<title>
|
|
5
|
-
<script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
|
|
6
|
-
<script>
|
|
7
|
-
$(document).on('contextmenu', function(e){ e.preventDefault(); });
|
|
8
|
-
</script>
|
|
4
|
+
<title>Obscured</title>
|
|
9
5
|
<style>
|
|
10
6
|
div {
|
|
11
|
-
width:
|
|
12
|
-
height:
|
|
7
|
+
width: 200px;
|
|
8
|
+
height: 200px;
|
|
9
|
+
}
|
|
10
|
+
#cover, #offscreen, #offscreen_wrapper {
|
|
13
11
|
position: absolute;
|
|
14
12
|
}
|
|
15
13
|
#obscured {
|
|
@@ -17,6 +15,7 @@
|
|
|
17
15
|
background-color: red;
|
|
18
16
|
}
|
|
19
17
|
#cover {
|
|
18
|
+
top: 0px;
|
|
20
19
|
z-index: 2;
|
|
21
20
|
background-color: blue;
|
|
22
21
|
}
|
|
@@ -33,12 +32,13 @@
|
|
|
33
32
|
}
|
|
34
33
|
</style>
|
|
35
34
|
</head>
|
|
36
|
-
|
|
37
|
-
<body id="with_animation">
|
|
35
|
+
<body>
|
|
38
36
|
<div id="obscured">
|
|
39
37
|
<input id="obscured_input"/>
|
|
40
38
|
</div>
|
|
41
39
|
<div id="cover"></div>
|
|
40
|
+
<iframe id="frameOne" height="10px" src="/frame_one"></iframe>
|
|
41
|
+
<iframe id="nestedFrames" src="/frame_parent"></iframe>
|
|
42
42
|
<div id="offscreen_wrapper">
|
|
43
43
|
<div id="offscreen"></div>
|
|
44
44
|
</div>
|
data/lib/capybara/version.rb
CHANGED
data/spec/sauce_spec_chrome.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
CHROME_DRIVER = :selenium_chrome
|
|
@@ -27,6 +28,11 @@ Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
|
|
|
27
28
|
Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
|
|
28
29
|
end
|
|
29
30
|
|
|
31
|
+
Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
|
|
32
|
+
subclass = Class.new(Capybara::Selenium::Driver)
|
|
33
|
+
subclass.new(app, browser: :chrome, options: browser_options, timeout: 30)
|
|
34
|
+
end
|
|
35
|
+
|
|
30
36
|
module TestSessions
|
|
31
37
|
Chrome = Capybara::Session.new(CHROME_DRIVER, TestApp)
|
|
32
38
|
end
|
|
@@ -46,8 +52,9 @@ end
|
|
|
46
52
|
|
|
47
53
|
RSpec.describe 'Capybara::Session with chrome' do
|
|
48
54
|
include Capybara::SpecHelper
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
56
|
+
include_examples examples, TestSessions::Chrome, CHROME_DRIVER
|
|
57
|
+
end
|
|
51
58
|
|
|
52
59
|
context 'storage' do
|
|
53
60
|
describe '#reset!' do
|
|
@@ -106,4 +113,12 @@ RSpec.describe 'Capybara::Session with chrome' do
|
|
|
106
113
|
expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
|
|
107
114
|
end
|
|
108
115
|
end
|
|
116
|
+
|
|
117
|
+
describe 'using subclass of selenium driver' do
|
|
118
|
+
it 'works' do
|
|
119
|
+
session = Capybara::Session.new(:selenium_driver_subclass_with_chrome, TestApp)
|
|
120
|
+
session.visit('/form')
|
|
121
|
+
expect(session).to have_current_path('/form')
|
|
122
|
+
end
|
|
123
|
+
end
|
|
109
124
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
def selenium_host
|
|
@@ -72,8 +73,9 @@ end
|
|
|
72
73
|
|
|
73
74
|
RSpec.describe 'Capybara::Session with remote Chrome' do
|
|
74
75
|
include Capybara::SpecHelper
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
77
|
+
include_examples examples, TestSessions::Chrome, CHROME_REMOTE_DRIVER
|
|
78
|
+
end
|
|
77
79
|
|
|
78
80
|
it 'is considered to be chrome' do
|
|
79
81
|
expect(session.driver.browser.browser).to eq :chrome
|
data/spec/selenium_spec_edge.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
Capybara.register_driver :selenium_edge do |app|
|
|
@@ -27,6 +28,7 @@ end
|
|
|
27
28
|
|
|
28
29
|
RSpec.describe 'Capybara::Session with Edge', capybara_skip: skipped_tests do
|
|
29
30
|
include Capybara::SpecHelper
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
32
|
+
include_examples examples, TestSessions::SeleniumEdge, :selenium_edge
|
|
33
|
+
end
|
|
32
34
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
browser_options = ::Selenium::WebDriver::Firefox::Options.new
|
|
@@ -68,8 +69,9 @@ end
|
|
|
68
69
|
|
|
69
70
|
RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/MultipleDescribes
|
|
70
71
|
include Capybara::SpecHelper
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
73
|
+
include_examples examples, TestSessions::SeleniumFirefox, :selenium_firefox
|
|
74
|
+
end
|
|
73
75
|
|
|
74
76
|
describe 'filling in Firefox-specific date and time fields with keystrokes' do
|
|
75
77
|
let(:datetime) { Time.new(1983, 6, 19, 6, 30) }
|
|
@@ -198,13 +200,4 @@ RSpec.describe Capybara::Selenium::Node do
|
|
|
198
200
|
expect(session).to have_link('Has been alt control meta')
|
|
199
201
|
end
|
|
200
202
|
end
|
|
201
|
-
|
|
202
|
-
context '#send_keys' do
|
|
203
|
-
it 'should process space' do
|
|
204
|
-
session = TestSessions::SeleniumFirefox
|
|
205
|
-
session.visit('/form')
|
|
206
|
-
session.find(:css, '#address1_city').send_keys('ocean', [:shift, :space, 'side'])
|
|
207
|
-
expect(session.find(:css, '#address1_city').value).to eq 'ocean SIDE'
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
203
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
def selenium_host
|
|
@@ -77,8 +78,9 @@ end
|
|
|
77
78
|
|
|
78
79
|
RSpec.describe 'Capybara::Session with remote firefox' do
|
|
79
80
|
include Capybara::SpecHelper
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
82
|
+
include_examples examples, TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER
|
|
83
|
+
end
|
|
82
84
|
|
|
83
85
|
it 'is considered to be firefox' do
|
|
84
86
|
expect(session.driver.browser.browser).to eq :firefox
|
data/spec/selenium_spec_ie.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
if ENV['CI']
|
|
@@ -39,7 +40,6 @@ Capybara.register_driver :selenium_ie do |app|
|
|
|
39
40
|
browser: :remote,
|
|
40
41
|
options: options,
|
|
41
42
|
url: url).tap do |driver|
|
|
42
|
-
puts driver.browser.capabilities.inspect
|
|
43
43
|
driver.browser.file_detector = lambda do |args|
|
|
44
44
|
str = args.first.to_s
|
|
45
45
|
str if File.exist?(str)
|
|
@@ -50,9 +50,7 @@ Capybara.register_driver :selenium_ie do |app|
|
|
|
50
50
|
app,
|
|
51
51
|
browser: :ie,
|
|
52
52
|
options: options
|
|
53
|
-
)
|
|
54
|
-
puts driver.browser.capabilities.inspect
|
|
55
|
-
end
|
|
53
|
+
)
|
|
56
54
|
end
|
|
57
55
|
end
|
|
58
56
|
|
|
@@ -117,8 +115,9 @@ end
|
|
|
117
115
|
|
|
118
116
|
RSpec.describe 'Capybara::Session with Internet Explorer', capybara_skip: skipped_tests do # rubocop:disable RSpec/MultipleDescribes
|
|
119
117
|
include Capybara::SpecHelper
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
119
|
+
include_examples examples, TestSessions::SeleniumIE, :selenium_ie
|
|
120
|
+
end
|
|
122
121
|
end
|
|
123
122
|
|
|
124
123
|
RSpec.describe Capybara::Selenium::Node do
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'selenium-webdriver'
|
|
5
5
|
require 'shared_selenium_session'
|
|
6
|
+
require 'shared_selenium_node'
|
|
6
7
|
require 'rspec/shared_spec_matchers'
|
|
7
8
|
|
|
8
9
|
SAFARI_DRIVER = :selenium_safari
|
|
@@ -54,13 +55,6 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
|
|
|
54
55
|
pending 'safaridriver thinks these links are non-interactable for some unknown reason'
|
|
55
56
|
when /Capybara::Session selenium_safari #attach_file with a block can upload by clicking the file input/
|
|
56
57
|
skip "safaridriver doesn't allow clicking on file inputs"
|
|
57
|
-
when /Capybara::Session selenium_safari #attach_file with a block can upload by clicking the label/
|
|
58
|
-
skip 'hangs tests'
|
|
59
|
-
when /Capybara::Session selenium_safari #check when checkbox hidden with Capybara.automatic_label_click == false with allow_label_click == true should check via the label if input is visible but blocked by another element/,
|
|
60
|
-
'Capybara::Session selenium_safari node #click should not retry clicking when wait is disabled',
|
|
61
|
-
'Capybara::Session selenium_safari node #click should allow to retry longer',
|
|
62
|
-
'Capybara::Session selenium_safari node #click should retry clicking'
|
|
63
|
-
pending "safaridriver doesn't return a specific enough error to deal with this"
|
|
64
58
|
when /Capybara::Session selenium_safari #within_frame works if the frame is closed/,
|
|
65
59
|
/Capybara::Session selenium_safari #switch_to_frame works if the frame is closed/
|
|
66
60
|
skip 'Safari has a race condition when clicking an element that causes the frame to close. It will sometimes raise a NoSuchFrameError'
|
|
@@ -79,15 +73,14 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
|
|
|
79
73
|
when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
|
|
80
74
|
'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
|
|
81
75
|
skip 'safaridriver loses the ability to find elements in the document after `go_back`'
|
|
82
|
-
when 'Capybara::Session selenium_safari node #send_keys should hold modifiers at top level'
|
|
83
|
-
skip 'Need to look into this'
|
|
84
76
|
end
|
|
85
77
|
end
|
|
86
78
|
|
|
87
79
|
RSpec.describe 'Capybara::Session with safari' do
|
|
88
80
|
include Capybara::SpecHelper
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
['Capybara::Session', 'Capybara::Node', Capybara::RSpecMatchers].each do |examples|
|
|
82
|
+
include_examples examples, TestSessions::Safari, SAFARI_DRIVER
|
|
83
|
+
end
|
|
91
84
|
|
|
92
85
|
context 'storage' do
|
|
93
86
|
describe '#reset!' do
|
|
@@ -125,17 +118,18 @@ RSpec.describe 'Capybara::Session with safari' do
|
|
|
125
118
|
let(:session) { TestSessions::Safari }
|
|
126
119
|
|
|
127
120
|
before do
|
|
128
|
-
skip 'Too many other things broken currently'
|
|
129
121
|
session.visit('/form')
|
|
130
122
|
end
|
|
131
123
|
|
|
132
124
|
it 'should fill in a date input with a String' do
|
|
125
|
+
pending "Safari doesn't support date inputs"
|
|
133
126
|
session.fill_in('form_date', with: '06/19/1983')
|
|
134
127
|
session.click_button('awesome')
|
|
135
128
|
expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
|
|
136
129
|
end
|
|
137
130
|
|
|
138
131
|
it 'should fill in a time input with a String' do
|
|
132
|
+
# Safari doesn't support time inputs - so this is just a text input
|
|
139
133
|
session.fill_in('form_time', with: '06:30A')
|
|
140
134
|
session.click_button('awesome')
|
|
141
135
|
results = extract_results(session)['time']
|
|
@@ -143,6 +137,7 @@ RSpec.describe 'Capybara::Session with safari' do
|
|
|
143
137
|
end
|
|
144
138
|
|
|
145
139
|
it 'should fill in a datetime input with a String' do
|
|
140
|
+
pending "Safari doesn't support datetime inputs"
|
|
146
141
|
session.fill_in('form_datetime', with: "06/19/1983\t06:30A")
|
|
147
142
|
session.click_button('awesome')
|
|
148
143
|
expect(Time.parse(extract_results(session)['datetime'])).to eq datetime
|
data/spec/server_spec.rb
CHANGED
|
@@ -83,8 +83,10 @@ RSpec.describe Capybara::Server do
|
|
|
83
83
|
server = Capybara::Server.new(app).boot
|
|
84
84
|
|
|
85
85
|
expect do
|
|
86
|
-
Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/
|
|
87
|
-
end.to
|
|
86
|
+
Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
|
|
87
|
+
end.to(raise_error do |e|
|
|
88
|
+
expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
|
|
89
|
+
end)
|
|
88
90
|
|
|
89
91
|
res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
|
|
90
92
|
https.get('/')
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'selenium-webdriver'
|
|
5
|
+
|
|
6
|
+
RSpec.shared_examples 'Capybara::Node' do |session, _mode|
|
|
7
|
+
let(:session) { session }
|
|
8
|
+
|
|
9
|
+
context '#content_editable?' do
|
|
10
|
+
it 'returns true when the element is content editable' do
|
|
11
|
+
session.visit('/with_js')
|
|
12
|
+
expect(session.find(:css, '#existing_content_editable').base.content_editable?).to be true
|
|
13
|
+
expect(session.find(:css, '#existing_content_editable_child').base.content_editable?).to be true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns false when the element is not content editable' do
|
|
17
|
+
session.visit('/with_js')
|
|
18
|
+
expect(session.find(:css, '#drag').base.content_editable?).to be false
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context '#send_keys' do
|
|
23
|
+
it 'should process space' do
|
|
24
|
+
session.visit('/form')
|
|
25
|
+
session.find(:css, '#address1_city').send_keys('ocean', [:shift, :space, 'side'])
|
|
26
|
+
expect(session.find(:css, '#address1_city').value).to eq 'ocean SIDE'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
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.20.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: 2019-05-
|
|
13
|
+
date: 2019-05-15 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: addressable
|
|
@@ -96,6 +96,20 @@ dependencies:
|
|
|
96
96
|
- - "~>"
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '1.2'
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
name: uglifier
|
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '0'
|
|
106
|
+
type: :runtime
|
|
107
|
+
prerelease: false
|
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - ">="
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '0'
|
|
99
113
|
- !ruby/object:Gem::Dependency
|
|
100
114
|
name: xpath
|
|
101
115
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -487,6 +501,10 @@ files:
|
|
|
487
501
|
- lib/capybara/selector/regexp_disassembler.rb
|
|
488
502
|
- lib/capybara/selector/selector.rb
|
|
489
503
|
- lib/capybara/selector/xpath_extensions.rb
|
|
504
|
+
- lib/capybara/selenium/atoms/getAttribute.min.js
|
|
505
|
+
- lib/capybara/selenium/atoms/isDisplayed.min.js
|
|
506
|
+
- lib/capybara/selenium/atoms/src/getAttribute.js
|
|
507
|
+
- lib/capybara/selenium/atoms/src/isDisplayed.js
|
|
490
508
|
- lib/capybara/selenium/driver.rb
|
|
491
509
|
- lib/capybara/selenium/driver_specializations/chrome_driver.rb
|
|
492
510
|
- lib/capybara/selenium/driver_specializations/firefox_driver.rb
|
|
@@ -501,6 +519,7 @@ files:
|
|
|
501
519
|
- lib/capybara/selenium/nodes/firefox_node.rb
|
|
502
520
|
- lib/capybara/selenium/nodes/ie_node.rb
|
|
503
521
|
- lib/capybara/selenium/nodes/safari_node.rb
|
|
522
|
+
- lib/capybara/selenium/patches/atoms.rb
|
|
504
523
|
- lib/capybara/selenium/patches/pause_duration_fix.rb
|
|
505
524
|
- lib/capybara/selenium/patches/persistent_client.rb
|
|
506
525
|
- lib/capybara/server.rb
|
|
@@ -607,6 +626,7 @@ files:
|
|
|
607
626
|
- lib/capybara/spec/session/within_spec.rb
|
|
608
627
|
- lib/capybara/spec/spec_helper.rb
|
|
609
628
|
- lib/capybara/spec/test_app.rb
|
|
629
|
+
- lib/capybara/spec/views/animated.erb
|
|
610
630
|
- lib/capybara/spec/views/buttons.erb
|
|
611
631
|
- lib/capybara/spec/views/fieldsets.erb
|
|
612
632
|
- lib/capybara/spec/views/form.erb
|
|
@@ -680,6 +700,7 @@ files:
|
|
|
680
700
|
- spec/selenium_spec_safari.rb
|
|
681
701
|
- spec/server_spec.rb
|
|
682
702
|
- spec/session_spec.rb
|
|
703
|
+
- spec/shared_selenium_node.rb
|
|
683
704
|
- spec/shared_selenium_session.rb
|
|
684
705
|
- spec/spec_helper.rb
|
|
685
706
|
- spec/xpath_builder_spec.rb
|