capybara 3.27.0 → 3.28.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 +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
|
[![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)
|
8
8
|
[![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)
|
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
|