capybara 3.13.2 → 3.14.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 +16 -1
- data/README.md +2 -2
- data/lib/capybara.rb +13 -6
- data/lib/capybara/node/base.rb +11 -4
- data/lib/capybara/rack_test/driver.rb +4 -0
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/node.rb +18 -2
- data/lib/capybara/selenium/driver.rb +5 -0
- data/lib/capybara/selenium/extensions/find.rb +3 -3
- data/lib/capybara/selenium/extensions/html5_drag.rb +52 -1
- data/lib/capybara/selenium/nodes/chrome_node.rb +7 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +7 -0
- data/lib/capybara/spec/public/test.js +1 -0
- data/lib/capybara/spec/session/node_spec.rb +9 -0
- data/lib/capybara/spec/session/scroll_spec.rb +1 -1
- data/lib/capybara/spec/session/within_spec.rb +23 -0
- data/lib/capybara/spec/test_app.rb +2 -2
- data/lib/capybara/spec/views/with_hover.erb +1 -0
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/shared_selenium_session.rb +29 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f79ad67119c7cc637fcab5cbc4fe95b0d80a76c2c38182f2a6b8beb3564f8448
|
4
|
+
data.tar.gz: 9d5c1ca24bbc3e7f2a9c18c71c5b61a78b96d24147b21c9b0f753217d4fc2772
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a799dc6db1032d812bf749ca8ee8ca8b46e59e957130f80ddfb9d5c2b08fce1a543ce3a0e9c28ee2bf38470867bc6d8a64ce6ed3f3d6c32ae3f31f41c071cb8f
|
7
|
+
data.tar.gz: d41beb222470a77bd2f2784a8def99ef3fc4b2928ee1b50cb66167d1764a94ec7ea1be59424c4d09f2a7981b3c6ba47ee6df02b13d6472480f10d9698c742e82
|
data/History.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# Version 3.14
|
2
|
+
Release date: 2019-02-25
|
3
|
+
|
4
|
+
### Added
|
5
|
+
|
6
|
+
* rack_test driver now supports reloading elements when the document changes - Issue #2157
|
7
|
+
* Selenium driver HTML5 drag-drop emulation now emits multiple move events so drag direction
|
8
|
+
is determinable [Erkki Eilonen, Thomas Walpole]
|
9
|
+
* Capybara.server_errors now defaults to [Exception] - Issue #2160 [Edgars Beigarts]
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
* Workaround hover issue with FF 65 - Issue #2156
|
13
|
+
* Workaround chromedriver issue when setting blank strings to react controlled text fields
|
14
|
+
* Workaround chromedriver issue with popup windows not loading content - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
|
15
|
+
|
1
16
|
# Version 3.13.2
|
2
17
|
Release date: 2019-01-24
|
3
18
|
|
@@ -22,7 +37,7 @@ Release date: 2019-01-23
|
|
22
37
|
* Speed optimizations around multiple element location and path generation when using the Selenium driver
|
23
38
|
* Support for locator type checking in custom selectors
|
24
39
|
* Allow configuration of gumbo use - defaults to off
|
25
|
-
* `assert_style`/`has_style`/`have_style`
|
40
|
+
* `assert_style`/`has_style`/`have_style` deprecated in favor of `assert_matches_style`/`matches_styles?`/`match_style`
|
26
41
|
* :style filter added to selectors
|
27
42
|
|
28
43
|
# Version 3.12.0
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
[](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
[](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
8
8
|
|
9
|
-
**Note** You are viewing the README for the
|
9
|
+
**Note** You are viewing the README for the 3.14.x version of Capybara.
|
10
10
|
|
11
11
|
Capybara helps you test web applications by simulating how a real user would
|
12
12
|
interact with your app. It is agnostic about the driver running your tests and
|
@@ -409,7 +409,7 @@ and test server, see [Transactions and database setup](#transactions-and-databas
|
|
409
409
|
|
410
410
|
### <a name="apparition"></a>Apparition
|
411
411
|
|
412
|
-
The [apparition driver](https://github.com/twalpole/apparition) in a new driver
|
412
|
+
The [apparition driver](https://github.com/twalpole/apparition) in a new driver that allows you to run tests using Chrome in a headless
|
413
413
|
or headed configuration. It attempts to provide backwards compatibility with the [Poltergeist driver API](https://github.com/teampoltergeist/poltergeist)
|
414
414
|
while allowing for the use of modern JS/CSS. It uses CDP to communicate with Chrome, thereby obviating the need for chromedriver.
|
415
415
|
A compatibility layer for capybara-webkit is planned, although has not yet been started. This driver is being developed by the
|
data/lib/capybara.rb
CHANGED
@@ -73,7 +73,7 @@ module Capybara
|
|
73
73
|
# [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
|
74
74
|
# [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
|
75
75
|
# [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
|
76
|
-
# [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [
|
76
|
+
# [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [Exception])
|
77
77
|
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
|
78
78
|
# [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
|
79
79
|
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
|
@@ -516,7 +516,7 @@ Capybara.configure do |config|
|
|
516
516
|
config.exact = false
|
517
517
|
config.exact_text = false
|
518
518
|
config.raise_server_errors = true
|
519
|
-
config.server_errors = [
|
519
|
+
config.server_errors = [Exception]
|
520
520
|
config.visible_text_only = false
|
521
521
|
config.automatic_label_click = false
|
522
522
|
config.enable_aria_label = false
|
@@ -544,13 +544,20 @@ Capybara.register_driver :selenium_headless do |app|
|
|
544
544
|
end
|
545
545
|
|
546
546
|
Capybara.register_driver :selenium_chrome do |app|
|
547
|
-
|
547
|
+
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
|
548
|
+
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
|
549
|
+
opts.args << '--disable-site-isolation-trials'
|
550
|
+
end
|
551
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
548
552
|
end
|
549
553
|
|
550
554
|
Capybara.register_driver :selenium_chrome_headless do |app|
|
551
555
|
Capybara::Selenium::Driver.load_selenium
|
552
|
-
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
553
|
-
|
554
|
-
|
556
|
+
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
|
557
|
+
opts.args << '--headless'
|
558
|
+
opts.args << '--disable-gpu' if Gem.win_platform?
|
559
|
+
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
|
560
|
+
opts.args << '--disable-site-isolation-trials'
|
561
|
+
end
|
555
562
|
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
556
563
|
end
|
data/lib/capybara/node/base.rb
CHANGED
@@ -83,11 +83,18 @@ module Capybara
|
|
83
83
|
yield
|
84
84
|
rescue StandardError => err
|
85
85
|
session.raise_server_error!
|
86
|
-
raise err unless
|
87
|
-
raise err if timer.expired?
|
86
|
+
raise err unless catch_error?(err, errors)
|
88
87
|
|
89
|
-
|
90
|
-
|
88
|
+
if driver.wait?
|
89
|
+
raise err if timer.expired?
|
90
|
+
|
91
|
+
sleep(0.01)
|
92
|
+
reload if session_options.automatic_reload
|
93
|
+
else
|
94
|
+
old_base = @base
|
95
|
+
reload if session_options.automatic_reload
|
96
|
+
raise err if old_base == @base
|
97
|
+
end
|
91
98
|
retry
|
92
99
|
ensure
|
93
100
|
session.synchronized = false
|
@@ -102,4 +102,8 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
|
|
102
102
|
def put(*args, &block); browser.put(*args, &block); end
|
103
103
|
def delete(*args, &block); browser.delete(*args, &block); end
|
104
104
|
def header(key, value); browser.header(key, value); end
|
105
|
+
|
106
|
+
def invalid_element_errors
|
107
|
+
[Capybara::RackTest::Errors::StaleElementReferenceError]
|
108
|
+
end
|
105
109
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'capybara/rack_test/errors'
|
4
|
+
|
3
5
|
class Capybara::RackTest::Node < Capybara::Driver::Node
|
4
6
|
BLOCK_ELEMENTS = %w[p h1 h2 h3 h4 h5 h6 ol ul pre address blockquote dl div fieldset form hr noscript table].freeze
|
5
7
|
|
@@ -106,14 +108,24 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
106
108
|
native.path
|
107
109
|
end
|
108
110
|
|
109
|
-
def find_xpath(locator)
|
111
|
+
def find_xpath(locator, **_hints)
|
110
112
|
native.xpath(locator).map { |el| self.class.new(driver, el) }
|
111
113
|
end
|
112
114
|
|
113
|
-
def find_css(locator)
|
115
|
+
def find_css(locator, **_hints)
|
114
116
|
native.css(locator, Capybara::RackTest::CSSHandlers.new).map { |el| self.class.new(driver, el) }
|
115
117
|
end
|
116
118
|
|
119
|
+
public_instance_methods(false).each do |meth_name|
|
120
|
+
alias_method "unchecked_#{meth_name}", meth_name
|
121
|
+
private "unchecked_#{meth_name}" # rubocop:disable Layout/AccessModifierIndentation,Style/AccessModifierDeclarations
|
122
|
+
|
123
|
+
define_method meth_name do |*args|
|
124
|
+
stale_check
|
125
|
+
send("unchecked_#{meth_name}", *args)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
117
129
|
def ==(other)
|
118
130
|
native == other.native
|
119
131
|
end
|
@@ -141,6 +153,10 @@ protected
|
|
141
153
|
|
142
154
|
private
|
143
155
|
|
156
|
+
def stale_check
|
157
|
+
raise Capybara::RackTest::Errors::StaleElementReferenceError unless native.document == driver.dom
|
158
|
+
end
|
159
|
+
|
144
160
|
def deselect_options
|
145
161
|
select_node.find_xpath('.//option[@selected]').each { |node| node.native.remove_attribute('selected') }
|
146
162
|
end
|
@@ -386,6 +386,11 @@ private
|
|
386
386
|
raise Capybara::ExpectationNotMet, 'Timed out waiting for Selenium session reset' if timer.expired?
|
387
387
|
|
388
388
|
sleep 0.01
|
389
|
+
|
390
|
+
# It has been observed that it is possible that asynchronous JS code in
|
391
|
+
# the application under test can navigate the browser away from about:blank
|
392
|
+
# if the timing is just right. Ensure we are still at about:blank...
|
393
|
+
@browser.navigate.to('about:blank') unless current_url == 'about:blank'
|
389
394
|
end
|
390
395
|
end
|
391
396
|
|
@@ -77,9 +77,9 @@ module Capybara
|
|
77
77
|
def is_displayed_atom # rubocop:disable Naming/PredicateName
|
78
78
|
@@is_displayed_atom ||= begin
|
79
79
|
browser.send(:bridge).send(:read_atom, 'isDisplayed')
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
rescue StandardError
|
81
|
+
# If the atom doesn't exist or other error
|
82
|
+
''
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -30,6 +30,44 @@ class Capybara::Selenium::Node
|
|
30
30
|
var source = arguments[0];
|
31
31
|
var target = arguments[1];
|
32
32
|
|
33
|
+
function rectCenter(rect){
|
34
|
+
return new DOMPoint(
|
35
|
+
(rect.left + rect.right)/2,
|
36
|
+
(rect.top + rect.bottom)/2
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
function pointOnRect(pt, rect) {
|
41
|
+
var rectPt = rectCenter(rect);
|
42
|
+
var slope = (rectPt.y - pt.y) / (rectPt.x - pt.x);
|
43
|
+
|
44
|
+
if (pt.x <= rectPt.x) { // left side
|
45
|
+
var minXy = slope * (rect.left - pt.x) + pt.y;
|
46
|
+
if (rect.top <= minXy && minXy <= rect.bottom)
|
47
|
+
return new DOMPoint(rect.left, minXy);
|
48
|
+
}
|
49
|
+
|
50
|
+
if (pt.x >= rectPt.x) { // right side
|
51
|
+
var maxXy = slope * (rect.right - pt.x) + pt.y;
|
52
|
+
if (rect.top <= maxXy && maxXy <= rect.bottom)
|
53
|
+
return new DOMPoint(rect.right, maxXy);
|
54
|
+
}
|
55
|
+
|
56
|
+
if (pt.y <= rectPt.y) { // top side
|
57
|
+
var minYx = (rectPt.top - pt.y) / slope + pt.x;
|
58
|
+
if (rect.left <= minYx && minYx <= rect.right)
|
59
|
+
return new DOMPoint(minYx, rect.top);
|
60
|
+
}
|
61
|
+
|
62
|
+
if (pt.y >= rectPt.y) { // bottom side
|
63
|
+
var maxYx = (rect.bottom - pt.y) / slope + pt.x;
|
64
|
+
if (rect.left <= maxYx && maxYx <= rect.right)
|
65
|
+
return new DOMPoint(maxYx, rect.bottom);
|
66
|
+
}
|
67
|
+
|
68
|
+
return new DOMPoint(pt.x,pt.y);
|
69
|
+
}
|
70
|
+
|
33
71
|
var dt = new DataTransfer();
|
34
72
|
var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
|
35
73
|
|
@@ -41,11 +79,24 @@ class Capybara::Selenium::Node
|
|
41
79
|
dt.setData('text/uri-list', source.src);
|
42
80
|
dt.setData('text', source.src);
|
43
81
|
}
|
82
|
+
|
44
83
|
var dragEvent = new DragEvent('dragstart', opts);
|
45
84
|
source.dispatchEvent(dragEvent);
|
46
85
|
target.scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'});
|
47
|
-
var
|
86
|
+
var targetRect = target.getBoundingClientRect();
|
87
|
+
var sourceCenter = rectCenter(source.getBoundingClientRect());
|
88
|
+
|
89
|
+
// fire 2 dragover events to simulate dragging with a direction
|
90
|
+
var entryPoint = pointOnRect(sourceCenter, targetRect)
|
91
|
+
var dragOverOpts = Object.assign({clientX: entryPoint.x, clientY: entryPoint.y}, opts);
|
92
|
+
var dragOverEvent = new DragEvent('dragover', dragOverOpts);
|
48
93
|
target.dispatchEvent(dragOverEvent);
|
94
|
+
|
95
|
+
var targetCenter = rectCenter(targetRect);
|
96
|
+
dragOverOpts = Object.assign({clientX: targetCenter.x, clientY: targetCenter.y}, opts);
|
97
|
+
dragOverEvent = new DragEvent('dragover', dragOverOpts);
|
98
|
+
target.dispatchEvent(dragOverEvent);
|
99
|
+
|
49
100
|
var dragLeaveEvent = new DragEvent('dragleave', opts);
|
50
101
|
target.dispatchEvent(dragLeaveEvent);
|
51
102
|
if (dragOverEvent.defaultPrevented) {
|
@@ -5,6 +5,13 @@ require 'capybara/selenium/extensions/html5_drag'
|
|
5
5
|
class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
|
6
6
|
include Html5Drag
|
7
7
|
|
8
|
+
def set_text(value, clear: nil, **_unused)
|
9
|
+
super.tap do
|
10
|
+
# React doesn't see the chromedriver element clear
|
11
|
+
send_keys(:space, :backspace) if value.to_s.empty? && clear.nil?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
def set_file(value) # rubocop:disable Naming/AccessorMethodName
|
9
16
|
super(value)
|
10
17
|
rescue ::Selenium::WebDriver::Error::ExpectedError => err
|
@@ -58,6 +58,13 @@ class Capybara::Selenium::FirefoxNode < Capybara::Selenium::Node
|
|
58
58
|
html5_drag_to(element)
|
59
59
|
end
|
60
60
|
|
61
|
+
def hover
|
62
|
+
return super unless browser_version >= 65.0
|
63
|
+
|
64
|
+
# work around issue 2156 - https://github.com/teamcapybara/capybara/issues/2156
|
65
|
+
scroll_if_needed { browser_action.move_to(native, 0, 0).move_to(native).perform }
|
66
|
+
end
|
67
|
+
|
61
68
|
private
|
62
69
|
|
63
70
|
def click_with_options(click_options)
|
@@ -13,6 +13,7 @@ $(function() {
|
|
13
13
|
ev.originalEvent.dataTransfer.setData("text", ev.target.id);
|
14
14
|
});
|
15
15
|
$('#drop_html5, #drop_html5_scroll').on('dragover', function(ev){
|
16
|
+
$(this).after('<div class="log">DragOver with client position: ' + ev.clientX + ',' + ev.clientY)
|
16
17
|
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
17
18
|
});
|
18
19
|
$('#drop_html5, #drop_html5_scroll').on('drop', function(ev){
|
@@ -344,6 +344,15 @@ Capybara::SpecHelper.spec 'node' do
|
|
344
344
|
@session.find(:css, '.wrapper.scroll_needed').hover
|
345
345
|
expect(@session.find(:css, '.wrapper.scroll_needed .hidden_until_hover', visible: false)).to be_visible
|
346
346
|
end
|
347
|
+
|
348
|
+
it 'should hover again after following a link and back' do
|
349
|
+
@session.visit('/with_hover')
|
350
|
+
@session.find(:css, '.wrapper:not(.scroll_needed)').hover
|
351
|
+
@session.click_link('Other hover page')
|
352
|
+
@session.click_link('Go back')
|
353
|
+
@session.find(:css, '.wrapper:not(.scroll_needed)').hover
|
354
|
+
expect(@session.find(:css, '.wrapper:not(.scroll_needed) .hidden_until_hover', visible: false)).to be_visible
|
355
|
+
end
|
347
356
|
end
|
348
357
|
|
349
358
|
describe '#click' do
|
@@ -108,7 +108,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
|
|
108
108
|
expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [50, 75]
|
109
109
|
end
|
110
110
|
|
111
|
-
it 'can scroll the scroll the scrolling element by a
|
111
|
+
it 'can scroll the scroll the scrolling element by a specific amount' do
|
112
112
|
scrolling_element = @session.find(:css, '#scrollable')
|
113
113
|
scrolling_element.scroll_to 100, 100
|
114
114
|
scrolling_element.scroll_to(:current, offset: [-50, 50])
|
@@ -26,6 +26,29 @@ Capybara::SpecHelper.spec '#within' do
|
|
26
26
|
end
|
27
27
|
expect(@session).to have_content('Bar')
|
28
28
|
end
|
29
|
+
|
30
|
+
it 'should reload the node if the page is changed' do
|
31
|
+
@session.within(:css, '#for_foo') do
|
32
|
+
@session.visit('/with_scope_other')
|
33
|
+
expect(@session).to have_content('Different text')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should reload multiple nodes if the page is changed' do
|
38
|
+
@session.within(:css, '#for_bar') do
|
39
|
+
@session.within(:css, 'form[action="/redirect"]') do
|
40
|
+
@session.refresh
|
41
|
+
expect(@session).to have_content('First Name')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should error if the page is changed and a matching node no longer exists' do
|
47
|
+
@session.within(:css, '#for_foo') do
|
48
|
+
@session.visit('/')
|
49
|
+
expect { @session.text }.to raise_error(StandardError)
|
50
|
+
end
|
51
|
+
end
|
29
52
|
end
|
30
53
|
|
31
54
|
context 'with XPath selector' do
|
@@ -6,8 +6,8 @@ require 'rack'
|
|
6
6
|
require 'yaml'
|
7
7
|
|
8
8
|
class TestApp < Sinatra::Base
|
9
|
-
class TestAppError <
|
10
|
-
class TestAppOtherError <
|
9
|
+
class TestAppError < Exception; end # rubocop:disable Lint/InheritException
|
10
|
+
class TestAppOtherError < Exception # rubocop:disable Lint/InheritException
|
11
11
|
def initialize(string1, msg)
|
12
12
|
@something = string1
|
13
13
|
@message = msg
|
@@ -10,6 +10,7 @@
|
|
10
10
|
.hidden_until_hover {display: none;}
|
11
11
|
.wrapper:hover .hidden_until_hover { display: block }
|
12
12
|
</style>
|
13
|
+
<a href='with_hover1'>Other hover page</a>
|
13
14
|
<div class="wrapper">
|
14
15
|
Some text here so the wrapper has size
|
15
16
|
<div class="hidden_until_hover">Here I am</div>
|
data/lib/capybara/version.rb
CHANGED
@@ -307,6 +307,15 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
307
307
|
expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
|
308
308
|
end
|
309
309
|
|
310
|
+
it 'should set clientX/Y in dragover events' do
|
311
|
+
session.visit('/with_js')
|
312
|
+
element = session.find('//div[@id="drag_html5"]')
|
313
|
+
target = session.find('//div[@id="drop_html5"]')
|
314
|
+
element.drag_to(target)
|
315
|
+
session.all(:css, 'div.log').each { |el| puts el.text }
|
316
|
+
expect(session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
|
317
|
+
end
|
318
|
+
|
310
319
|
it 'should not HTML5 drag and drop on a non HTML5 drop element' do
|
311
320
|
session.visit('/with_js')
|
312
321
|
element = session.find('//div[@id="drag_html5"]')
|
@@ -453,6 +462,26 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
453
462
|
expect(session).to have_selector(:element, "{custom}": 'abcdef')
|
454
463
|
end
|
455
464
|
end
|
465
|
+
|
466
|
+
describe 'with react' do
|
467
|
+
context 'controlled components' do
|
468
|
+
it 'can set and clear a text field' do
|
469
|
+
session.visit 'https://reactjs.org/docs/forms.html'
|
470
|
+
session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
|
471
|
+
sleep 2 # give codepen a chance to stabilize result frame
|
472
|
+
session.within_frame(:css, 'iframe.result-iframe') do
|
473
|
+
session.fill_in('Name:', with: 'abc')
|
474
|
+
session.accept_prompt 'A name was submitted: abc' do
|
475
|
+
session.click_button('Submit')
|
476
|
+
end
|
477
|
+
session.fill_in('Name:', with: '')
|
478
|
+
session.accept_prompt(/A name was submitted: $/) do
|
479
|
+
session.click_button('Submit')
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
456
485
|
end
|
457
486
|
|
458
487
|
def headless_or_remote?
|
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.14.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-
|
13
|
+
date: 2019-02-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -375,6 +375,7 @@ files:
|
|
375
375
|
- lib/capybara/rack_test/browser.rb
|
376
376
|
- lib/capybara/rack_test/css_handlers.rb
|
377
377
|
- lib/capybara/rack_test/driver.rb
|
378
|
+
- lib/capybara/rack_test/errors.rb
|
378
379
|
- lib/capybara/rack_test/form.rb
|
379
380
|
- lib/capybara/rack_test/node.rb
|
380
381
|
- lib/capybara/rails.rb
|
@@ -541,12 +542,14 @@ files:
|
|
541
542
|
- lib/capybara/spec/views/with_count.erb
|
542
543
|
- lib/capybara/spec/views/with_fixed_header_footer.erb
|
543
544
|
- lib/capybara/spec/views/with_hover.erb
|
545
|
+
- lib/capybara/spec/views/with_hover1.erb
|
544
546
|
- lib/capybara/spec/views/with_html.erb
|
545
547
|
- lib/capybara/spec/views/with_html5_svg.erb
|
546
548
|
- lib/capybara/spec/views/with_html_entities.erb
|
547
549
|
- lib/capybara/spec/views/with_js.erb
|
548
550
|
- lib/capybara/spec/views/with_namespace.erb
|
549
551
|
- lib/capybara/spec/views/with_scope.erb
|
552
|
+
- lib/capybara/spec/views/with_scope_other.erb
|
550
553
|
- lib/capybara/spec/views/with_simple_html.erb
|
551
554
|
- lib/capybara/spec/views/with_slow_unload.erb
|
552
555
|
- lib/capybara/spec/views/with_title.erb
|