capybara 3.13.2 → 3.14.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 +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
|
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
8
8
|
|
9
|
-
**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
|