capybara 3.20.1 → 3.21.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.
@@ -8,19 +8,14 @@ module Capybara
8
8
  # Find an {Capybara::Node::Element} based on the given arguments. +find+ will raise an error if the element
9
9
  # is not found.
10
10
  #
11
- # @!macro waiting_behavior
12
- # If the driver is capable of executing JavaScript, this method will wait for a set amount of time
13
- # and continuously retry finding the element until either the element is found or the time
14
- # expires. The length of time +find+ will wait is controlled through {Capybara.default_max_wait_time}
15
- # and defaults to 2 seconds.
16
- # @option options [false, true, Numeric] wait (Capybara.default_max_wait_time) Maximum time to wait for matching element to appear.
17
- #
18
11
  # page.find('#foo').find('.bar')
19
12
  # page.find(:xpath, './/div[contains(., "bar")]')
20
13
  # page.find('li', text: 'Quox').click_link('Delete')
21
14
  #
22
15
  # @param (see Capybara::Node::Finders#all)
23
16
  #
17
+ # @macro waiting_behavior
18
+ #
24
19
  # @!macro system_filters
25
20
  # @option options [String, Regexp] text Only find elements which contain this text or match this regexp
26
21
  # @option options [String, Boolean] exact_text (Capybara.exact_text) When String the elements contained text must match exactly, when Boolean controls whether the :text option must match exactly
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Capybara.add_selector(:css, locator_type: [String, Symbol], raw_locator: true) do
4
- css { |css| css }
4
+ css do |css|
5
+ warn "DEPRECATED: Passing a symbol (#{css.inspect}) as the CSS locator is deprecated - please pass a string instead." if css.is_a? Symbol
6
+ css
7
+ end
5
8
  end
@@ -166,11 +166,11 @@ module Capybara
166
166
  end
167
167
 
168
168
  def min_repeat
169
- @exp.quantifier&.min || 1
169
+ @exp.repetitions.begin
170
170
  end
171
171
 
172
172
  def max_repeat
173
- @exp.quantifier&.max || 1
173
+ @exp.repetitions.end
174
174
  end
175
175
 
176
176
  def fixed_repeat?
@@ -22,6 +22,69 @@ class Capybara::Selenium::Node
22
22
  native.property('draggable')
23
23
  end
24
24
 
25
+ def html5_drop(*args)
26
+ if args[0].is_a? String
27
+ input = driver.evaluate_script ATTACH_FILE
28
+ input.set_file(args)
29
+ driver.execute_script DROP_FILE, self, input
30
+ else
31
+ items = args.each_with_object([]) do |arg, arr|
32
+ arg.each_with_object(arr) do |(type, data), arr_|
33
+ arr_ << { type: type, data: data }
34
+ end
35
+ end
36
+ driver.execute_script DROP_STRING, items, self
37
+ end
38
+ end
39
+
40
+ DROP_STRING = <<~JS
41
+ var strings = arguments[0],
42
+ el = arguments[1],
43
+ dt = new DataTransfer(),
44
+ opts = { cancelable: true, bubbles: true, dataTransfer: dt };
45
+ for (var i=0; i < strings.length; i++){
46
+ if (dt.items) {
47
+ dt.items.add(strings[i]['data'], strings[i]['type']);
48
+ } else {
49
+ dt.setData(strings[i]['type'], strings[i]['data']);
50
+ }
51
+ }
52
+ var dropEvent = new DragEvent('drop', opts);
53
+ el.dispatchEvent(dropEvent);
54
+ JS
55
+
56
+ DROP_FILE = <<~JS
57
+ var el = arguments[0],
58
+ input = arguments[1],
59
+ files = input.files,
60
+ dt = new DataTransfer(),
61
+ opts = { cancelable: true, bubbles: true, dataTransfer: dt };
62
+ input.parentElement.removeChild(input);
63
+ if (dt.items){
64
+ for (var i=0; i<files.length; i++){
65
+ dt.items.add(files[i]);
66
+ }
67
+ } else {
68
+ Object.defineProperty(dt, "files", {
69
+ value: files,
70
+ writable: false
71
+ });
72
+ }
73
+ var dropEvent = new DragEvent('drop', opts);
74
+ el.dispatchEvent(dropEvent);
75
+ JS
76
+
77
+ ATTACH_FILE = <<~JS
78
+ (function(){
79
+ var input = document.createElement('INPUT');
80
+ input.type = "file";
81
+ input.id = "_capybara_drop_file";
82
+ input.multiple = true;
83
+ document.body.appendChild(input);
84
+ return input;
85
+ })()
86
+ JS
87
+
25
88
  MOUSEDOWN_TRACKER = <<~JS
26
89
  document.addEventListener('mousedown', ev => {
27
90
  window.capybara_mousedown_prevented = ev.defaultPrevented;
@@ -137,6 +137,10 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
137
137
  element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
138
138
  end
139
139
 
140
+ def drop(*_)
141
+ raise NotImplementedError, 'Out of browser drop emulation is not implemented for the current browser'
142
+ end
143
+
140
144
  def tag_name
141
145
  @tag_name ||= native.tag_name.downcase
142
146
  end
@@ -34,6 +34,10 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
34
34
  html5_drag_to(element)
35
35
  end
36
36
 
37
+ def drop(*args)
38
+ html5_drop(*args)
39
+ end
40
+
37
41
  def click(*)
38
42
  super
39
43
  rescue ::Selenium::WebDriver::Error::WebDriverError => e
@@ -52,6 +52,10 @@ class Capybara::Selenium::FirefoxNode < Capybara::Selenium::Node
52
52
  html5_drag_to(element)
53
53
  end
54
54
 
55
+ def drop(*args)
56
+ html5_drop(*args)
57
+ end
58
+
55
59
  def hover
56
60
  return super unless browser_version >= 65.0
57
61
 
@@ -117,19 +121,6 @@ private
117
121
  driver.browser.capabilities[:browser_version].to_f
118
122
  end
119
123
 
120
- DISABLED_BY_FIELDSET_XPATH = XPath.generate do |x|
121
- x.parent(:fieldset)[
122
- x.attr(:disabled)
123
- ] + x.ancestor[
124
- ~x.self(:legend) |
125
- x.preceding_sibling(:legend)
126
- ][
127
- x.parent(:fieldset)[
128
- x.attr(:disabled)
129
- ]
130
- ]
131
- end.to_s.freeze
132
-
133
124
  class ModifierKeysStack
134
125
  def initialize
135
126
  @stack = []
@@ -4,8 +4,19 @@ require 'capybara/selenium/extensions/html5_drag'
4
4
 
5
5
  class Capybara::Selenium::IENode < Capybara::Selenium::Node
6
6
  def disabled?
7
- # TODO: Doesn't work for a bunch of cases - need to get IE running to see if it can be done like this
8
- # driver.evaluate_script("arguments[0].msMatchesSelector(':disabled, select:disabled *')", self)
9
- super
7
+ # super
8
+ # optimize to one script call
9
+ driver.evaluate_script <<~JS.delete("\n"), self
10
+ arguments[0].msMatchesSelector('
11
+ :disabled,
12
+ select:disabled *,
13
+ optgroup:disabled *,
14
+ fieldset[disabled],
15
+ fieldset[disabled] > *:not(legend),
16
+ fieldset[disabled] > *:not(legend) *,
17
+ fieldset[disabled] > legend:nth-of-type(n+2),
18
+ fieldset[disabled] > legend:nth-of-type(n+2) *
19
+ ')
20
+ JS
10
21
  end
11
22
  end
@@ -91,19 +91,6 @@ private
91
91
  driver.browser.send(:bridge)
92
92
  end
93
93
 
94
- DISABLED_BY_FIELDSET_XPATH = XPath.generate do |x|
95
- x.parent(:fieldset)[
96
- x.attr(:disabled)
97
- ] + x.ancestor[
98
- ~x.self(:legend) |
99
- x.preceding_sibling(:legend)
100
- ][
101
- x.parent(:fieldset)[
102
- x.attr(:disabled)
103
- ]
104
- ]
105
- end.to_s.freeze
106
-
107
94
  def _send_keys(keys, actions = browser_action, down_keys = ModifierKeysStack.new)
108
95
  case keys
109
96
  when *MODIFIER_KEYS
@@ -18,7 +18,33 @@ $(function() {
18
18
  });
19
19
  $('#drop_html5, #drop_html5_scroll').on('drop', function(ev){
20
20
  ev.preventDefault();
21
- $(this).html('HTML5 Dropped ' + ev.originalEvent.dataTransfer.getData("text"));
21
+ var oev = ev.originalEvent;
22
+ if (oev.dataTransfer.items) {
23
+ for (var i = 0; i < oev.dataTransfer.items.length; i++){
24
+ var item = oev.dataTransfer.items[i];
25
+ if (item.kind === 'file'){
26
+ var file = item.getAsFile();
27
+ $(this).append('HTML5 Dropped file: ' + file.name);
28
+ } else {
29
+ var _this = this;
30
+ var callback = (function(type){
31
+ return function(s){
32
+ $(_this).append('HTML5 Dropped string: ' + type + ' ' + s)
33
+ }
34
+ })(item.type);
35
+ item.getAsString(callback);
36
+ }
37
+ }
38
+ } else {
39
+ $(this).html('HTML5 Dropped ' + oev.dataTransfer.getData("text"));
40
+ for (var i = 0; i < oev.dataTransfer.files.length; i++) {
41
+ $(this).append('HTML5 Dropped file: ' + oev.dataTransfer.files[i].name);
42
+ }
43
+ for (var i = 0; i < oev.dataTransfer.types.length; i++) {
44
+ var type = oev.dataTransfer.types[i];
45
+ $(this).append('HTML5 Dropped string: ' + type + ' ' + oev.dataTransfer.getData(type));
46
+ }
47
+ }
22
48
  });
23
49
  $('#clickable').click(function(e) {
24
50
  var link = $(this);
@@ -180,7 +206,7 @@ $(function() {
180
206
  sessionStorage.setItem('session', 'session_value');
181
207
  localStorage.setItem('local', 'local value');
182
208
  });
183
- $('#multiple-file').change(function(e){
184
- $('body').append($('<p class="file_change"input_event_triggered">File input changed</p>'));
209
+ $('#multiple-file, #hidden_file').change(function(e){
210
+ $('body').append($('<p class="file_change">File input changed</p>'));
185
211
  })
186
212
  });
@@ -180,6 +180,12 @@ Capybara::SpecHelper.spec '#attach_file' do
180
180
  @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
181
181
  expect(@session.evaluate_script('arguments[0].style.display', @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
182
182
  end
183
+
184
+ it 'should fire change' do
185
+ @session.visit('/with_js')
186
+ @session.attach_file('hidden_file', with_os_path_separators(__FILE__), make_visible: true)
187
+ expect(@session).to have_css('.file_change')
188
+ end
183
189
  end
184
190
 
185
191
  context 'with a block', requires: %i[js] do
@@ -198,11 +204,13 @@ Capybara::SpecHelper.spec '#attach_file' do
198
204
  @session.click_button('awesome')
199
205
  expect(extract_results(@session)['hidden_image']).to end_with(File.basename(__FILE__))
200
206
  end
201
- end
202
207
 
203
- private
204
-
205
- def with_os_path_separators(path)
206
- Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
208
+ it 'should fire change' do
209
+ @session.visit('/with_js')
210
+ @session.attach_file(with_os_path_separators(__FILE__)) do
211
+ @session.find(:label, 'Label for hidden file input').click
212
+ end
213
+ expect(@session).to have_css('.file_change')
214
+ end
207
215
  end
208
216
  end
@@ -10,10 +10,11 @@ Capybara::SpecHelper.spec '#has_css?' do
10
10
  expect(@session).to have_css('p a#foo')
11
11
  end
12
12
 
13
- it 'should take a symbol as the selector' do
13
+ it 'should warn when passed a symbol' do
14
14
  # This was never a specifically accepted format but it has worked for a
15
- # lot of versions. Probably should keep it until at least 4.0
16
- # TODO: consider not supporting symbol for the CSS selector.
15
+ # lot of versions.
16
+ # TODO: Remove in 4.0
17
+ expect_any_instance_of(Kernel).to receive(:warn) # rubocop:disable RSpec/AnyInstance
17
18
  expect(@session).to have_css(:p)
18
19
  end
19
20
 
@@ -242,6 +242,10 @@ Capybara::SpecHelper.spec 'node' do
242
242
  expect(@session.find('//div[@id="hidden_attr"]')).not_to be_visible
243
243
  expect(@session.find('//a[@id="hidden_attr_via_ancestor"]')).not_to be_visible
244
244
  expect(@session.find('//input[@id="hidden_input"]')).not_to be_visible
245
+ end
246
+
247
+ it 'template elements should not be visible' do
248
+ Capybara.ignore_hidden_elements = false
245
249
  expect(@session.find('//template')).not_to be_visible
246
250
  end
247
251
 
@@ -414,6 +418,87 @@ Capybara::SpecHelper.spec 'node' do
414
418
  link.drag_to target
415
419
  expect(@session).to have_xpath('//div[contains(., "Dropped!")]')
416
420
  end
421
+
422
+ context 'HTML5', requires: %i[js html5_drag] do
423
+ it 'should HTML5 drag and drop an object' do
424
+ @session.visit('/with_js')
425
+ element = @session.find('//div[@id="drag_html5"]')
426
+ target = @session.find('//div[@id="drop_html5"]')
427
+ element.drag_to(target)
428
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
429
+ end
430
+
431
+ it 'should set clientX/Y in dragover events' do
432
+ @session.visit('/with_js')
433
+ element = @session.find('//div[@id="drag_html5"]')
434
+ target = @session.find('//div[@id="drop_html5"]')
435
+ element.drag_to(target)
436
+ expect(@session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
437
+ end
438
+
439
+ it 'should not HTML5 drag and drop on a non HTML5 drop element' do
440
+ @session.visit('/with_js')
441
+ element = @session.find('//div[@id="drag_html5"]')
442
+ target = @session.find('//div[@id="drop_html5"]')
443
+ target.execute_script("$(this).removeClass('drop');")
444
+ element.drag_to(target)
445
+ sleep 1
446
+ expect(@session).not_to have_xpath('//div[contains(., "HTML5 Dropped")]')
447
+ end
448
+
449
+ it 'should HTML5 drag and drop when scrolling needed' do
450
+ @session.visit('/with_js')
451
+ element = @session.find('//div[@id="drag_html5_scroll"]')
452
+ target = @session.find('//div[@id="drop_html5_scroll"]')
453
+ element.drag_to(target)
454
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5_scroll")]')
455
+ end
456
+
457
+ it 'should drag HTML5 default draggable elements' do
458
+ @session.visit('/with_js')
459
+ link = @session.find_link('drag_link_html5')
460
+ target = @session.find(:id, 'drop_html5')
461
+ link.drag_to target
462
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
463
+ end
464
+ end
465
+ end
466
+
467
+ describe 'Element#drop', requires: %i[js html5_drag] do
468
+ it 'can drop a file' do
469
+ @session.visit('/with_js')
470
+ target = @session.find('//div[@id="drop_html5"]')
471
+ target.drop(
472
+ with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__)))
473
+ )
474
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
475
+ end
476
+
477
+ it 'can drop multiple files' do
478
+ @session.visit('/with_js')
479
+ target = @session.find('//div[@id="drop_html5"]')
480
+ target.drop(
481
+ with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))),
482
+ with_os_path_separators(File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__)))
483
+ )
484
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
485
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: test_file.txt")]')
486
+ end
487
+
488
+ it 'can drop strings' do
489
+ @session.visit('/with_js')
490
+ target = @session.find('//div[@id="drop_html5"]')
491
+ target.drop('text/plain' => 'Some dropped text')
492
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
493
+ end
494
+
495
+ it 'can drop multiple strings' do
496
+ @session.visit('/with_js')
497
+ target = @session.find('//div[@id="drop_html5"]')
498
+ target.drop('text/plain' => 'Some dropped text', 'text/url' => 'http://www.google.com')
499
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
500
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/url http://www.google.com")]')
501
+ end
417
502
  end
418
503
 
419
504
  describe '#hover', requires: [:hover] do
@@ -124,6 +124,10 @@ module Capybara
124
124
  def be_an_invalid_element_error(session)
125
125
  satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
126
126
  end
127
+
128
+ def with_os_path_separators(path)
129
+ Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
130
+ end
127
131
  end
128
132
  end
129
133
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.20.1'
4
+ VERSION = '3.21.0'
5
5
  end
data/lib/capybara.rb CHANGED
@@ -73,22 +73,24 @@ 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: [Exception])
76
+ # [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and {configure 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)
80
80
  # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
81
81
  # [save_path = String] Where to put pages saved through save_(page|screenshot), save_and_open_(page|screenshot) (Default: Dir.pwd)
82
- # [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
82
+ # [automatic_label_click = Boolean] Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check}, {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
83
83
  # [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
84
84
  # [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
85
85
  # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
86
- # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
87
- # [default_set_options = Hash] The default options passed to Node::set (Default: {})
86
+ # [server = Symbol] The name of the registered server to use when running the app under test (Default: :default which uses puma)
87
+ # [default_set_options = Hash] The default options passed to {Capybara::Node::Element#set Element#set} (Default: {})
88
88
  # [test_id = Symbol/String/nil] Optional attribute to match locator aginst with builtin selectors along with id (Default: nil)
89
- # [predicates_wait = Boolean] Whether Capybaras predicate matchers use waiting behavior by default (Default: true)
89
+ # [predicates_wait = Boolean] Whether Capybara's predicate matchers use waiting behavior by default (Default: true)
90
90
  # [default_normalize_ws = Boolean] Whether text predicates and matchers use normalize whitespace behaviour (Default: false)
91
91
  # [allow_gumbo = Boolean] When `nokogumbo` is available, whether it will be used to parse HTML strings (Default: false)
92
+ # [match = :one/:first/:prefer_exact/:smart] The matching strategy to find nodes (Default: :smart)
93
+ # [exact_text = Boolean] Whether the text matchers and `:text` filter match exactly or on substrings (Default: false)
92
94
  #
93
95
  # === DSL Options
94
96
  #
@@ -201,15 +203,13 @@ module Capybara
201
203
  # any string containing HTML in the exact same way you would query the current document in a Capybara
202
204
  # session.
203
205
  #
204
- # Example: A single element
205
- #
206
+ # @example A single element
206
207
  # node = Capybara.string('<a href="foo">bar</a>')
207
208
  # anchor = node.first('a')
208
209
  # anchor[:href] #=> 'foo'
209
210
  # anchor.text #=> 'bar'
210
211
  #
211
- # Example: Multiple elements
212
- #
212
+ # @example Multiple elements
213
213
  # node = Capybara.string <<-HTML
214
214
  # <ul>
215
215
  # <li id="home">Home</li>
@@ -297,7 +297,7 @@ module Capybara
297
297
 
298
298
  ##
299
299
  #
300
- # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver
300
+ # The current {Capybara::Session} based on what is set as {app} and {current_driver}.
301
301
  #
302
302
  # @return [Capybara::Session] The currently used session
303
303
  #
@@ -340,7 +340,7 @@ module Capybara
340
340
 
341
341
  ##
342
342
  #
343
- # Yield a block using a specific session name or Capybara::Session instance.
343
+ # Yield a block using a specific session name or {Capybara::Session} instance.
344
344
  #
345
345
  def using_session(name_or_session)
346
346
  previous_session_info = {
@@ -64,6 +64,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
64
64
  pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
65
65
  when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
66
66
  pending "Geckodriver doesn't allow clicking on file inputs"
67
+ when /drag_to.*HTML5/
68
+ pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
67
69
  end
68
70
  end
69
71
 
@@ -6,13 +6,13 @@ require 'shared_selenium_session'
6
6
  require 'shared_selenium_node'
7
7
  require 'rspec/shared_spec_matchers'
8
8
 
9
- if ENV['CI']
10
- if ::Selenium::WebDriver::Service.respond_to? :driver_path=
11
- ::Selenium::WebDriver::IE::Service
12
- else
13
- ::Selenium::WebDriver::IE
14
- end.driver_path = 'C:\Tools\WebDriver\IEDriverServer.exe'
15
- end
9
+ # if ENV['CI']
10
+ # if ::Selenium::WebDriver::Service.respond_to? :driver_path=
11
+ # ::Selenium::WebDriver::IE::Service
12
+ # else
13
+ # ::Selenium::WebDriver::IE
14
+ # end.driver_path = 'C:\Tools\WebDriver\IEDriverServer.exe'
15
+ # end
16
16
 
17
17
  def selenium_host
18
18
  ENV.fetch('SELENIUM_HOST', '192.168.56.102')
@@ -110,6 +110,12 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
110
110
  pending 'IE treats blank href as a parent request (against HTML spec)'
111
111
  when /#attach_file with a block/
112
112
  skip 'Hangs IE testing for unknown reason'
113
+ when /drag_to.*HTML5/
114
+ pending "IE doesn't support a DataTransfer constuctor"
115
+ when /template elements should not be visible/
116
+ skip "IE doesn't support template elements"
117
+ when /Element#drop/
118
+ pending "IE doesn't support DataTransfer constructor"
113
119
  end
114
120
  end
115
121
 
@@ -73,6 +73,8 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
73
73
  when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
74
74
  'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
75
75
  skip 'safaridriver loses the ability to find elements in the document after `go_back`'
76
+ when /drag_to.*HTML5/
77
+ pending "Safari doesn't support"
76
78
  end
77
79
  end
78
80
 
@@ -303,57 +303,6 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
303
303
  end
304
304
  end
305
305
 
306
- describe 'Element#drag_to' do
307
- before do
308
- skip "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, session)
309
- skip "IE doesn't support a DataTransfer constuctor" if ie?(session)
310
- skip "Safari doesn't support" if safari?(session)
311
- end
312
-
313
- it 'should HTML5 drag and drop an object' do
314
- session.visit('/with_js')
315
- element = session.find('//div[@id="drag_html5"]')
316
- target = session.find('//div[@id="drop_html5"]')
317
- element.drag_to(target)
318
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
319
- end
320
-
321
- it 'should set clientX/Y in dragover events' do
322
- session.visit('/with_js')
323
- element = session.find('//div[@id="drag_html5"]')
324
- target = session.find('//div[@id="drop_html5"]')
325
- element.drag_to(target)
326
- session.all(:css, 'div.log').each { |el| puts el.text }
327
- expect(session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
328
- end
329
-
330
- it 'should not HTML5 drag and drop on a non HTML5 drop element' do
331
- session.visit('/with_js')
332
- element = session.find('//div[@id="drag_html5"]')
333
- target = session.find('//div[@id="drop_html5"]')
334
- target.execute_script("$(this).removeClass('drop');")
335
- element.drag_to(target)
336
- sleep 1
337
- expect(session).not_to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
338
- end
339
-
340
- it 'should HTML5 drag and drop when scrolling needed' do
341
- session.visit('/with_js')
342
- element = session.find('//div[@id="drag_html5_scroll"]')
343
- target = session.find('//div[@id="drop_html5_scroll"]')
344
- element.drag_to(target)
345
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5_scroll")]')
346
- end
347
-
348
- it 'should drag HTML5 default draggable elements' do
349
- session.visit('/with_js')
350
- link = session.find_link('drag_link_html5')
351
- target = session.find(:id, 'drop_html5')
352
- link.drag_to target
353
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
354
- end
355
- end
356
-
357
306
  describe 'Capybara#Node#attach_file' do
358
307
  it 'can attach a directory' do
359
308
  pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
@@ -472,6 +421,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
472
421
  describe 'with react' do
473
422
  context 'controlled components' do
474
423
  it 'can set and clear a text field' do
424
+ skip "This test doesn't support older browsers" if ie?(session)
475
425
  # session.visit 'https://reactjs.org/docs/forms.html'
476
426
  # session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
477
427
  # copied into local view