capybara 3.27.0 → 3.28.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 +11 -0
- data/README.md +1 -1
- data/lib/capybara/node/element.rb +28 -1
- data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
- data/lib/capybara/registrations/servers.rb +5 -2
- data/lib/capybara/selector.rb +6 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selenium/driver.rb +4 -0
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +0 -4
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +6 -4
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +0 -6
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +0 -4
- data/lib/capybara/selenium/extensions/html5_drag.rb +10 -5
- data/lib/capybara/selenium/node.rb +29 -5
- data/lib/capybara/selenium/nodes/chrome_node.rb +0 -4
- data/lib/capybara/selenium/nodes/edge_node.rb +28 -12
- data/lib/capybara/selenium/nodes/firefox_node.rb +0 -4
- data/lib/capybara/selenium/nodes/safari_node.rb +0 -4
- data/lib/capybara/spec/session/has_field_spec.rb +18 -0
- data/lib/capybara/spec/session/node_spec.rb +14 -0
- data/lib/capybara/spec/views/form.erb +6 -1
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/selenium_spec_chrome_remote.rb +0 -6
- data/spec/selenium_spec_edge.rb +14 -15
- data/spec/selenium_spec_firefox_remote.rb +0 -6
- data/spec/selenium_spec_ie.rb +1 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59f170c7004d4936ffb0d136a4dd0755a9c1ec5870f6bf1114d693b99a8fed51
|
4
|
+
data.tar.gz: 955e163359d522952afdc7d776458667f97aa053e6eb704320733eae8340544a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13d33c4977455c5d2e9a5aa7532ffed98573795a1528685ded75574dfabd58512f5d3e71d3582d8155fe4325209ba3bbde3246a29b4436de573c5b492dffe1cc
|
7
|
+
data.tar.gz: 52b33d646ec5c86b61a04b7f2c354a1d1e77d1c363b0ba8d19e7ad1b48679a53078766c8f018f1d7f223b730d9b4d951f005a689a3f143999fdeead4c522242c
|
data/History.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# Version 3.28.0
|
2
|
+
Release date: 2019-08-03
|
3
|
+
|
4
|
+
### Added
|
5
|
+
|
6
|
+
* Allow forcing HTML5 or legacy dragging via the `:html5` option to `drag_to` when using Selenium with Chrome or Firefox
|
7
|
+
* Autodetection of drag type interprets not seeing the mousedown event as legacy.
|
8
|
+
* HTML5 form validation `:valid` node filter added to `:field` and `:fillable_field` selectors
|
9
|
+
* When using Capybara registered :puma server - patches Puma 4.0.x to fix SSL connection behavior. Removes
|
10
|
+
default `queue_requests` setting - Issue #2227
|
11
|
+
|
1
12
|
# Version 3.27.0
|
2
13
|
Release date: 2019-07-28
|
3
14
|
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
[](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
8
8
|
[](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
9
9
|
|
10
|
-
**Note** You are viewing the README for the 3.
|
10
|
+
**Note** You are viewing the README for the 3.28.x version of Capybara.
|
11
11
|
|
12
12
|
Capybara helps you test web applications by simulating how a real user would
|
13
13
|
interact with your app. It is agnostic about the driver running your tests and
|
@@ -396,8 +396,13 @@ module Capybara
|
|
396
396
|
#
|
397
397
|
# @param [Capybara::Node::Element] node The element to drag to
|
398
398
|
# @param [Hash] options Driver specific options for dragging. May not be supported by all drivers.
|
399
|
+
# @option options [Numeric] :delay (0.05) When using Chrome/Firefox with Selenium and HTML5 dragging this is the number
|
400
|
+
# of seconds between each stage of the drag.
|
401
|
+
# @option options [Boolean] :html5 When using Chrome/Firefox with Selenium enables to force the use of HTML5
|
402
|
+
# (true) or legacy (false) dragging. If not specified the driver will attempt to
|
403
|
+
# detect the correct method to use.
|
399
404
|
#
|
400
|
-
# @return [Capybara::Node::Element] The element
|
405
|
+
# @return [Capybara::Node::Element] The dragged element
|
401
406
|
def drag_to(node, **options)
|
402
407
|
synchronize { base.drag_to(node.base, **options) }
|
403
408
|
self
|
@@ -510,6 +515,28 @@ module Capybara
|
|
510
515
|
JS
|
511
516
|
end
|
512
517
|
|
518
|
+
##
|
519
|
+
#
|
520
|
+
# Toggle the elements background color between white and black for a period of time.
|
521
|
+
#
|
522
|
+
# @return [Capybara::Node::Element] The element
|
523
|
+
def flash
|
524
|
+
execute_script(<<~JS, 100)
|
525
|
+
async function flash(el, delay){
|
526
|
+
var old_bg = el.style.backgroundColor;
|
527
|
+
var colors = ["black", "white"];
|
528
|
+
for(var i=0; i<20; i++){
|
529
|
+
el.style.backgroundColor = colors[i % colors.length];
|
530
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
531
|
+
}
|
532
|
+
el.style.backgroundColor = old_bg;
|
533
|
+
}
|
534
|
+
flash(this, arguments[0]);
|
535
|
+
JS
|
536
|
+
|
537
|
+
self
|
538
|
+
end
|
539
|
+
|
513
540
|
# @api private
|
514
541
|
def reload
|
515
542
|
if @allow_reload
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Puma
|
4
|
+
module MiniSSL
|
5
|
+
class Socket
|
6
|
+
def read_nonblock(size, *_)
|
7
|
+
loop do
|
8
|
+
output = engine_read_all
|
9
|
+
return output if output
|
10
|
+
|
11
|
+
data = @socket.read_nonblock(size, exception: false)
|
12
|
+
raise IO::EAGAINWaitReadable if %i[wait_readable wait_writable].include? data
|
13
|
+
return nil if data.nil?
|
14
|
+
|
15
|
+
@engine.inject(data)
|
16
|
+
output = engine_read_all
|
17
|
+
|
18
|
+
return output if output
|
19
|
+
|
20
|
+
while (neg_data = @engine.extract)
|
21
|
+
@socket.write neg_data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -20,16 +20,19 @@ Capybara.register_server :puma do |app, port, host, **options|
|
|
20
20
|
raise LoadError, 'Capybara requires `puma` version 3.8.0 or higher, please upgrade `puma` or register and specify your own server block'
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
23
24
|
# If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
|
24
25
|
# Therefore construct and run the Server instance ourselves.
|
25
26
|
# Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
|
26
|
-
default_options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false
|
27
|
-
default_options[:queue_requests] = false if options[:Host]&.start_with?('ssl://')
|
27
|
+
default_options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }
|
28
28
|
options = default_options.merge(options)
|
29
29
|
|
30
30
|
conf = Rack::Handler::Puma.config(app, options)
|
31
31
|
events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
|
32
32
|
|
33
|
+
puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION)
|
34
|
+
require_relative 'patches/puma_ssl' if (Gem::Version.new('4.0.0')...Gem::Version.new('4.1.0')).cover? puma_ver
|
35
|
+
|
33
36
|
events.log 'Capybara starting Puma...'
|
34
37
|
events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
|
35
38
|
events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
|
data/lib/capybara/selector.rb
CHANGED
@@ -34,6 +34,7 @@ require 'capybara/selector/definition'
|
|
34
34
|
# * :unchecked (Boolean) - Match unchecked fields?
|
35
35
|
# * :disabled (Boolean, :all) - Match disabled field? (Default: false)
|
36
36
|
# * :multiple (Boolean) - Match fields that accept multiple values
|
37
|
+
# * :valid (Boolean) - Match fields that are valid/invalid according to HTML5 form validation
|
37
38
|
#
|
38
39
|
# * **:fieldset** - Select fieldset elements
|
39
40
|
# * Locator: Matches id, {Capybara.configure test_id}, or contents of wrapped legend
|
@@ -72,6 +73,7 @@ require 'capybara/selector/definition'
|
|
72
73
|
# * :type (String) - Matches the type attribute of the field or element type for 'textarea'
|
73
74
|
# * :disabled (Boolean, :all) - Match disabled field? (Default: false)
|
74
75
|
# * :multiple (Boolean) - Match fields that accept multiple values
|
76
|
+
# * :valid (Boolean) - Match fields that are valid/invalid according to HTML5 form validation
|
75
77
|
#
|
76
78
|
# * **:radio_button** - Find radio buttons
|
77
79
|
# * Locator: Match id, {Capybara.configure test_id} attribute, name, or associated label text
|
@@ -166,6 +168,7 @@ Capybara::Selector::FilterSet.add(:_field) do
|
|
166
168
|
node_filter(:checked, :boolean) { |node, value| !(value ^ node.checked?) }
|
167
169
|
node_filter(:unchecked, :boolean) { |node, value| (value ^ node.checked?) }
|
168
170
|
node_filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) }
|
171
|
+
node_filter(:valid, :boolean) { |node, value| node.evaluate_script('this.validity.valid') == value }
|
169
172
|
|
170
173
|
expression_filter(:name) { |xpath, val| xpath[XPath.attr(:name) == val] }
|
171
174
|
expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder) == val] }
|
@@ -182,12 +185,14 @@ Capybara::Selector::FilterSet.add(:_field) do
|
|
182
185
|
desc
|
183
186
|
end
|
184
187
|
|
185
|
-
describe(:node_filters) do |checked: nil, unchecked: nil, disabled: nil, **|
|
188
|
+
describe(:node_filters) do |checked: nil, unchecked: nil, disabled: nil, valid: nil, **|
|
186
189
|
desc, states = +'', []
|
187
190
|
states << 'checked' if checked || (unchecked == false)
|
188
191
|
states << 'not checked' if unchecked || (checked == false)
|
189
192
|
states << 'disabled' if disabled == true
|
190
193
|
desc << " that is #{states.join(' and ')}" unless states.empty?
|
194
|
+
desc << ' that is valid' if valid == true
|
195
|
+
desc << ' that is invalid' if valid == false
|
191
196
|
desc
|
192
197
|
end
|
193
198
|
end
|
@@ -18,7 +18,7 @@ Capybara.add_selector(:fillable_field, locator_type: [String, Symbol]) do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
filter_set(:_field, %i[disabled multiple name placeholder])
|
21
|
+
filter_set(:_field, %i[disabled multiple name placeholder valid])
|
22
22
|
|
23
23
|
node_filter(:with) do |node, with|
|
24
24
|
val = node.value
|
@@ -430,6 +430,10 @@ private
|
|
430
430
|
::Capybara::Selenium::Node.new(self, native_node, initial_cache)
|
431
431
|
end
|
432
432
|
|
433
|
+
def bridge
|
434
|
+
browser.send(:bridge)
|
435
|
+
end
|
436
|
+
|
433
437
|
def specialize_driver
|
434
438
|
browser_type = browser.browser
|
435
439
|
Capybara::Selenium::Driver.specializations.select { |k, _v| k === browser_type }.each_value do |specialization| # rubocop:disable Style/CaseEquality
|
@@ -3,6 +3,12 @@
|
|
3
3
|
require 'capybara/selenium/nodes/edge_node'
|
4
4
|
|
5
5
|
module Capybara::Selenium::Driver::EdgeDriver
|
6
|
+
def self.extended(base)
|
7
|
+
bridge = base.send(:bridge)
|
8
|
+
bridge.extend Capybara::Selenium::IsDisplayed unless bridge.commands(:is_element_displayed)
|
9
|
+
base.options[:native_displayed] = false if base.options[:native_displayed].nil?
|
10
|
+
end
|
11
|
+
|
6
12
|
def fullscreen_window(handle)
|
7
13
|
return super if edgedriver_version < 75
|
8
14
|
|
@@ -108,10 +114,6 @@ private
|
|
108
114
|
::Capybara::Selenium::EdgeNode.new(self, native_node, initial_cache)
|
109
115
|
end
|
110
116
|
|
111
|
-
def bridge
|
112
|
-
browser.send(:bridge)
|
113
|
-
end
|
114
|
-
|
115
117
|
def edgedriver_version
|
116
118
|
@edgedriver_version ||= begin
|
117
119
|
caps = browser.capabilities
|
@@ -13,12 +13,6 @@ module Capybara::Selenium::Driver::FirefoxDriver
|
|
13
13
|
(defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION.to_f >= 4)) ||
|
14
14
|
driver.browser.capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities)
|
15
15
|
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def bridge
|
20
|
-
browser.send(:bridge)
|
21
|
-
end
|
22
16
|
end
|
23
17
|
|
24
18
|
module Capybara::Selenium::Driver::W3CFirefoxDriver
|
@@ -18,10 +18,6 @@ private
|
|
18
18
|
def build_node(native_node, initial_cache = {})
|
19
19
|
::Capybara::Selenium::SafariNode.new(self, native_node, initial_cache)
|
20
20
|
end
|
21
|
-
|
22
|
-
def bridge
|
23
|
-
browser.send(:bridge)
|
24
|
-
end
|
25
21
|
end
|
26
22
|
|
27
23
|
Capybara::Selenium::Driver.register_specialization(/^(safari|Safari_Technology_Preview)$/,
|
@@ -4,13 +4,14 @@ class Capybara::Selenium::Node
|
|
4
4
|
module Html5Drag
|
5
5
|
# Implement methods to emulate HTML5 drag and drop
|
6
6
|
|
7
|
-
def drag_to(element, delay: 0.05)
|
7
|
+
def drag_to(element, html5: nil, delay: 0.05)
|
8
8
|
driver.execute_script MOUSEDOWN_TRACKER
|
9
9
|
scroll_if_needed { browser_action.click_and_hold(native).perform }
|
10
|
-
|
11
|
-
|
12
|
-
else
|
10
|
+
html5 = !driver.evaluate_script(LEGACY_DRAG_CHECK, self) if html5.nil?
|
11
|
+
if html5
|
13
12
|
perform_html5_drag(element, delay)
|
13
|
+
else
|
14
|
+
perform_legacy_drag(element)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -89,6 +90,7 @@ class Capybara::Selenium::Node
|
|
89
90
|
JS
|
90
91
|
|
91
92
|
MOUSEDOWN_TRACKER = <<~JS
|
93
|
+
window.capybara_mousedown_prevented = null;
|
92
94
|
document.addEventListener('mousedown', ev => {
|
93
95
|
window.capybara_mousedown_prevented = ev.defaultPrevented;
|
94
96
|
}, { once: true, passive: true })
|
@@ -96,7 +98,10 @@ class Capybara::Selenium::Node
|
|
96
98
|
|
97
99
|
LEGACY_DRAG_CHECK = <<~JS
|
98
100
|
(function(el){
|
99
|
-
if (window.capybara_mousedown_prevented)
|
101
|
+
if ([true, null].indexOf(window.capybara_mousedown_prevented) >= 0){
|
102
|
+
return true;
|
103
|
+
}
|
104
|
+
|
100
105
|
do {
|
101
106
|
if (el.draggable) return false;
|
102
107
|
} while (el = el.parentElement );
|
@@ -299,11 +299,31 @@ private
|
|
299
299
|
end
|
300
300
|
|
301
301
|
def set_file(value) # rubocop:disable Naming/AccessorMethodName
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
302
|
+
with_file_detector do
|
303
|
+
path_names = value.to_s.empty? ? [] : value
|
304
|
+
file_names = Array(path_names).map do |pn|
|
305
|
+
Pathname.new(pn).absolute? ? pn : File.expand_path(pn)
|
306
|
+
end.join("\n")
|
307
|
+
native.send_keys(file_names)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def with_file_detector
|
312
|
+
if driver.options[:browser] == :remote &&
|
313
|
+
bridge.respond_to?(:file_detector) &&
|
314
|
+
bridge.file_detector.nil?
|
315
|
+
begin
|
316
|
+
bridge.file_detector = lambda do |(fn, *)|
|
317
|
+
str = fn.to_s
|
318
|
+
str if File.exist?(str)
|
319
|
+
end
|
320
|
+
yield
|
321
|
+
ensure
|
322
|
+
bridge.file_detector = nil
|
323
|
+
end
|
324
|
+
else
|
325
|
+
yield
|
326
|
+
end
|
307
327
|
end
|
308
328
|
|
309
329
|
def set_content_editable(value) # rubocop:disable Naming/AccessorMethodName
|
@@ -359,6 +379,10 @@ private
|
|
359
379
|
driver.browser
|
360
380
|
end
|
361
381
|
|
382
|
+
def bridge
|
383
|
+
browser.send(:bridge)
|
384
|
+
end
|
385
|
+
|
362
386
|
def browser_action
|
363
387
|
browser.action
|
364
388
|
end
|
@@ -84,10 +84,6 @@ private
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
def bridge
|
88
|
-
driver.browser.send(:bridge)
|
89
|
-
end
|
90
|
-
|
91
87
|
def w3c?
|
92
88
|
(defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION.to_f >= 4)) ||
|
93
89
|
capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities)
|
@@ -36,14 +36,16 @@ class Capybara::Selenium::EdgeNode < Capybara::Selenium::Node
|
|
36
36
|
html5_drop(*args)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
def click(*)
|
40
|
+
super
|
41
|
+
rescue Selenium::WebDriver::Error::InvalidArgumentError => e
|
42
|
+
tag_name, type = attrs(:tagName, :type).map { |val| val&.downcase }
|
43
|
+
if tag_name == 'input' && type == 'file'
|
44
|
+
raise Selenium::WebDriver::Error::InvalidArgumentError, "EdgeChrome can't click on file inputs.\n#{e.message}"
|
45
|
+
end
|
46
|
+
|
47
|
+
raise
|
48
|
+
end
|
47
49
|
|
48
50
|
def disabled?
|
49
51
|
return super unless chrome_edge?
|
@@ -61,6 +63,18 @@ class Capybara::Selenium::EdgeNode < Capybara::Selenium::Node
|
|
61
63
|
click unless selected_or_disabled
|
62
64
|
end
|
63
65
|
|
66
|
+
def visible?
|
67
|
+
return super unless chrome_edge? && native_displayed?
|
68
|
+
|
69
|
+
begin
|
70
|
+
bridge.send(:execute, :is_element_displayed, id: native.ref)
|
71
|
+
rescue Selenium::WebDriver::Error::UnknownCommandError
|
72
|
+
# If the is_element_displayed command is unknown, no point in trying again
|
73
|
+
driver.options[:native_displayed] = false
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
64
78
|
private
|
65
79
|
|
66
80
|
def file_errors
|
@@ -69,10 +83,6 @@ private
|
|
69
83
|
end
|
70
84
|
end
|
71
85
|
|
72
|
-
def bridge
|
73
|
-
driver.browser.send(:bridge)
|
74
|
-
end
|
75
|
-
|
76
86
|
def browser_version
|
77
87
|
@browser_version ||= begin
|
78
88
|
caps = driver.browser.capabilities
|
@@ -83,4 +93,10 @@ private
|
|
83
93
|
def chrome_edge?
|
84
94
|
browser_version >= 75
|
85
95
|
end
|
96
|
+
|
97
|
+
def native_displayed?
|
98
|
+
(driver.options[:native_displayed] != false) &&
|
99
|
+
# chromedriver_supports_displayed_endpoint? &&
|
100
|
+
(!ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS'])
|
101
|
+
end
|
86
102
|
end
|
@@ -115,10 +115,6 @@ private
|
|
115
115
|
actions
|
116
116
|
end
|
117
117
|
|
118
|
-
def bridge
|
119
|
-
driver.browser.send(:bridge)
|
120
|
-
end
|
121
|
-
|
122
118
|
def upload(local_file)
|
123
119
|
return nil unless local_file
|
124
120
|
raise ArgumentError, "You may only upload files: #{local_file.inspect}" unless File.file?(local_file)
|
@@ -90,10 +90,6 @@ class Capybara::Selenium::SafariNode < Capybara::Selenium::Node
|
|
90
90
|
|
91
91
|
private
|
92
92
|
|
93
|
-
def bridge
|
94
|
-
driver.browser.send(:bridge)
|
95
|
-
end
|
96
|
-
|
97
93
|
def _send_keys(keys, actions = browser_action, down_keys = ModifierKeysStack.new)
|
98
94
|
case keys
|
99
95
|
when *MODIFIER_KEYS
|
@@ -93,6 +93,24 @@ Capybara::SpecHelper.spec '#has_field' do
|
|
93
93
|
expect(@session).not_to have_field('Html5 Multiple Email', multiple: false)
|
94
94
|
end
|
95
95
|
end
|
96
|
+
|
97
|
+
context 'with valid', requires: [:js] do
|
98
|
+
it 'should be true if field is valid' do
|
99
|
+
@session.fill_in 'required', with: 'something'
|
100
|
+
@session.fill_in 'length', with: 'abcd'
|
101
|
+
|
102
|
+
expect(@session).to have_field('required', valid: true)
|
103
|
+
expect(@session).to have_field('length', valid: true)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should be false if field is invalid' do
|
107
|
+
expect(@session).not_to have_field('required', valid: true)
|
108
|
+
expect(@session).to have_field('required', valid: false)
|
109
|
+
|
110
|
+
@session.fill_in 'length', with: 'abc'
|
111
|
+
expect(@session).not_to have_field('length', valid: true)
|
112
|
+
end
|
113
|
+
end
|
96
114
|
end
|
97
115
|
|
98
116
|
Capybara::SpecHelper.spec '#has_no_field' do
|
@@ -444,6 +444,20 @@ Capybara::SpecHelper.spec 'node' do
|
|
444
444
|
end
|
445
445
|
end
|
446
446
|
|
447
|
+
it 'should work with jsTree' do
|
448
|
+
@session.visit('/with_jstree')
|
449
|
+
@session.within(:css, '#container') do
|
450
|
+
@session.assert_text(/A.*B.*C/m)
|
451
|
+
source = @session.find(:css, '#j1_1_anchor')
|
452
|
+
target = @session.find(:css, '#j1_2_anchor')
|
453
|
+
|
454
|
+
source.drag_to(target)
|
455
|
+
|
456
|
+
@session.assert_no_text(/A.*B.*C/m)
|
457
|
+
@session.assert_text(/B.*C/m)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
447
461
|
context 'HTML5', requires: %i[js html5_drag] do
|
448
462
|
it 'should HTML5 drag and drop an object' do
|
449
463
|
@session.visit('/with_js')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
<h1>Form</h1>
|
3
3
|
|
4
|
-
<form action="/form" method="post">
|
4
|
+
<form action="/form" method="post" novalidate>
|
5
5
|
|
6
6
|
<p>
|
7
7
|
<label for="form_title">Title</label>
|
@@ -460,6 +460,11 @@ New line after and before textarea tag
|
|
460
460
|
<input id="readonly" name="form[readonly_test]" readonly/>
|
461
461
|
<input id="not_readonly" name="form[readonly_test]" />
|
462
462
|
</p>
|
463
|
+
|
464
|
+
<p>
|
465
|
+
<input id="required" name="form[required]" required />
|
466
|
+
<input id="length" name="form[length]" minlength="4" maxlength="4" />
|
467
|
+
</p>
|
463
468
|
</form>
|
464
469
|
|
465
470
|
<input type="text" name="form[outside_input]" value="outside_input" form="form1"/>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
5
|
+
<title>with_jstree</title>
|
6
|
+
</head>
|
7
|
+
<body id="with_jstree">
|
8
|
+
<div id="container">
|
9
|
+
<ul>
|
10
|
+
<li>Child node A</li>
|
11
|
+
<li>Child node B</li>
|
12
|
+
<li>Child node C</li>
|
13
|
+
</ul>
|
14
|
+
</div>
|
15
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
16
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.8/jstree.min.js"></script>
|
17
|
+
<script>
|
18
|
+
$(function () {
|
19
|
+
$('#container').jstree({
|
20
|
+
"core" : { "check_callback" : true }, // so that operations work
|
21
|
+
"plugins" : ["dnd"]
|
22
|
+
});
|
23
|
+
});
|
24
|
+
</script>
|
25
|
+
</body>
|
26
|
+
</html>
|
data/lib/capybara/version.rb
CHANGED
@@ -54,12 +54,6 @@ module TestSessions
|
|
54
54
|
Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
|
55
55
|
end
|
56
56
|
|
57
|
-
TestSessions::Chrome.driver.browser.file_detector = lambda do |args|
|
58
|
-
# args => ["/path/to/file"]
|
59
|
-
str = args.first.to_s
|
60
|
-
str if File.exist?(str)
|
61
|
-
end
|
62
|
-
|
63
57
|
skipped_tests = %i[response_headers status_code trigger download]
|
64
58
|
|
65
59
|
Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
|
data/spec/selenium_spec_edge.rb
CHANGED
@@ -6,16 +6,19 @@ require 'shared_selenium_session'
|
|
6
6
|
require 'shared_selenium_node'
|
7
7
|
require 'rspec/shared_spec_matchers'
|
8
8
|
|
9
|
-
unless ENV['CI']
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
# unless ENV['CI']
|
10
|
+
# Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
|
11
|
+
# end
|
13
12
|
|
14
|
-
|
13
|
+
if ::Selenium::WebDriver::Platform.mac?
|
14
|
+
Selenium::WebDriver::EdgeChrome.path = '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev'
|
15
|
+
end
|
15
16
|
|
16
17
|
Capybara.register_driver :selenium_edge do |app|
|
17
18
|
# ::Selenium::WebDriver.logger.level = "debug"
|
18
|
-
|
19
|
+
# If we don't create an options object the path set above won't be used
|
20
|
+
browser_options = ::Selenium::WebDriver::EdgeChrome::Options.new
|
21
|
+
Capybara::Selenium::Driver.new(app, browser: :edge_chrome, options: browser_options).tap do |driver|
|
19
22
|
driver.browser
|
20
23
|
driver.download_path = Capybara.save_path
|
21
24
|
end
|
@@ -27,17 +30,13 @@ end
|
|
27
30
|
|
28
31
|
skipped_tests = %i[response_headers status_code trigger]
|
29
32
|
|
30
|
-
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::
|
33
|
+
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::EdgeChrome) if ENV['CI']
|
31
34
|
|
32
35
|
Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
|
33
|
-
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
# skip 'Crashes'
|
38
|
-
# when /when Capybara.always_include_port is true/
|
39
|
-
# skip 'Crashes'
|
40
|
-
# end
|
36
|
+
case example.metadata[:full_description]
|
37
|
+
when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
|
38
|
+
pending "EdgeChrome doesn't allow clicking on file inputs"
|
39
|
+
end
|
41
40
|
end
|
42
41
|
|
43
42
|
RSpec.describe 'Capybara::Session with Edge', capybara_skip: skipped_tests do
|
@@ -50,12 +50,6 @@ module TestSessions
|
|
50
50
|
RemoteFirefox = Capybara::Session.new(FIREFOX_REMOTE_DRIVER, TestApp)
|
51
51
|
end
|
52
52
|
|
53
|
-
TestSessions::RemoteFirefox.driver.browser.file_detector = lambda do |args|
|
54
|
-
# args => ["/path/to/file"]
|
55
|
-
str = args.first.to_s
|
56
|
-
str if File.exist?(str)
|
57
|
-
end
|
58
|
-
|
59
53
|
skipped_tests = %i[response_headers status_code trigger download]
|
60
54
|
|
61
55
|
Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
|
data/spec/selenium_spec_ie.rb
CHANGED
@@ -39,12 +39,7 @@ Capybara.register_driver :selenium_ie do |app|
|
|
39
39
|
Capybara::Selenium::Driver.new(app,
|
40
40
|
browser: :remote,
|
41
41
|
options: options,
|
42
|
-
url: url)
|
43
|
-
driver.browser.file_detector = lambda do |args|
|
44
|
-
str = args.first.to_s
|
45
|
-
str if File.exist?(str)
|
46
|
-
end
|
47
|
-
end
|
42
|
+
url: url)
|
48
43
|
else
|
49
44
|
Capybara::Selenium::Driver.new(
|
50
45
|
app,
|
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.28.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-08-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -451,6 +451,7 @@ files:
|
|
451
451
|
- lib/capybara/rack_test/node.rb
|
452
452
|
- lib/capybara/rails.rb
|
453
453
|
- lib/capybara/registrations/drivers.rb
|
454
|
+
- lib/capybara/registrations/patches/puma_ssl.rb
|
454
455
|
- lib/capybara/registrations/servers.rb
|
455
456
|
- lib/capybara/result.rb
|
456
457
|
- lib/capybara/rspec.rb
|
@@ -668,6 +669,7 @@ files:
|
|
668
669
|
- lib/capybara/spec/views/with_html5_svg.erb
|
669
670
|
- lib/capybara/spec/views/with_html_entities.erb
|
670
671
|
- lib/capybara/spec/views/with_js.erb
|
672
|
+
- lib/capybara/spec/views/with_jstree.erb
|
671
673
|
- lib/capybara/spec/views/with_namespace.erb
|
672
674
|
- lib/capybara/spec/views/with_scope.erb
|
673
675
|
- lib/capybara/spec/views/with_scope_other.erb
|