capybara 3.7.1 → 3.7.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff4996d8188f7398e7998aa1295fca9e92ece2bee9a2d662a77ab66a182d7884
4
- data.tar.gz: 05f243132820c10cf6c6e49a032cbebb390d270c88655d4410d79c827cca7467
3
+ metadata.gz: 69837ab6d5097f6be64bc1010b230653cce9bdd318634c6efb19903a4cbb1f34
4
+ data.tar.gz: 6db7692bb7609c9d2ae488eb10dd3472c32071a473a0524e87265afe3a03ac6d
5
5
  SHA512:
6
- metadata.gz: eabe1a0080dea2a6cdce45eb65707ebd1696f6fca805eec2e1cad1cbbb3aed9f2a87f61e072401968845778607a50f14bcf36231827cbcacc0d88fe6785021f1
7
- data.tar.gz: 716a3b11ad853a8d0440cfb21a1e7c0975f9cbcb409dcc2daac92bbbd71b6f47f8d1312fed4881fe49ce312c8093ec3cc55d12080f78ca75ba7c9514f67ba565
6
+ metadata.gz: 4088bda8abff78614b6b93e61bd3e239e2e9de857ce34fe104d62a195cacf66f8512da44a26f1646aee9a4114e5d3f2eca6ebc4d54b8fc5ed3362b845e15f6b9
7
+ data.tar.gz: 2194129a44a0b636d09b1ae36639ebf893bb8816f3de6361b938f2ac281e8d2ecc045d9d862545df90d5b8827082f066fa0aef324b0a5b598f780b975a268da2
data/History.md CHANGED
@@ -1,3 +1,12 @@
1
+ # Version 3.7.2
2
+ Release date: 2018-09-12
3
+
4
+ ### Fixed
5
+
6
+ * Fix MatchQuery based matchers when used on a root element found using any type of parent/ancestor query - Issue #2097
7
+
8
+ * Fix Chrome/FF HTML5 drag simulation for elements (a, img) which default to draggable - Issue #2098
9
+
1
10
  # Version 3.7.1
2
11
  Release date: 2018-09-05
3
12
 
@@ -713,7 +713,7 @@ module Capybara
713
713
  query_args = _set_query_session_options(*query_args)
714
714
  query = Capybara::Queries::MatchQuery.new(*query_args, &optional_filter_block)
715
715
  synchronize(query.wait) do
716
- yield query.resolve_for(first(:xpath, './parent::*', minimum: 0) || query_scope)
716
+ yield query.resolve_for(first(:xpath, './parent::*', minimum: 0) || session&.document || query_scope)
717
717
  end
718
718
  true
719
719
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Capybara::Selenium::Node
4
+ module Html5Drag
5
+ private
6
+
7
+ def html5_drag_to(element)
8
+ driver.execute_script MOUSEDOWN_TRACKER
9
+ scroll_if_needed { browser_action.click_and_hold(native).perform }
10
+ if driver.evaluate_script('window.capybara_mousedown_prevented')
11
+ element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
12
+ else
13
+ driver.execute_script HTML5_DRAG_DROP_SCRIPT, self, element
14
+ end
15
+ end
16
+
17
+ def draggable?
18
+ # Workaround https://github.com/SeleniumHQ/selenium/issues/6396
19
+ driver.evaluate_script('arguments[0]["draggable"]', self) == true
20
+ end
21
+
22
+ MOUSEDOWN_TRACKER = <<~JS
23
+ if (!window.hasOwnProperty('capybara_mousedown_prevented')){
24
+ document.addEventListener('mousedown', function(ev){
25
+ window.capybara_mousedown_prevented = ev.defaultPrevented;
26
+ })
27
+ }
28
+ JS
29
+
30
+ HTML5_DRAG_DROP_SCRIPT = <<~JS
31
+ var source = arguments[0];
32
+ var target = arguments[1];
33
+
34
+ var dt = new DataTransfer();
35
+ var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
36
+
37
+ if (source.tagName == 'A'){
38
+ dt.setData('text/uri-list', source.href);
39
+ dt.setData('text', source.href);
40
+ }
41
+ if (source.tagName == 'IMG'){
42
+ dt.setData('text/uri-list', source.src);
43
+ dt.setData('text', source.src);
44
+ }
45
+ var dragEvent = new DragEvent('dragstart', opts);
46
+ source.dispatchEvent(dragEvent);
47
+ target.scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'});
48
+ var dragOverEvent = new DragEvent('dragover', opts);
49
+ target.dispatchEvent(dragOverEvent);
50
+ var dragLeaveEvent = new DragEvent('dragleave', opts);
51
+ target.dispatchEvent(dragLeaveEvent);
52
+ if (dragOverEvent.defaultPrevented) {
53
+ var dropEvent = new DragEvent('drop', opts);
54
+ target.dispatchEvent(dropEvent);
55
+ }
56
+ var dragEndEvent = new DragEvent('dragend', opts);
57
+ source.dispatchEvent(dragEndEvent);
58
+ JS
59
+ end
60
+ end
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'capybara/selenium/extensions/html5_drag'
4
+
3
5
  class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
6
+ include Html5Drag
7
+
4
8
  def set_file(value) # rubocop:disable Naming/AccessorMethodName
5
9
  super(value)
6
10
  rescue ::Selenium::WebDriver::Error::ExpectedError => err
@@ -11,10 +15,8 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
11
15
  end
12
16
 
13
17
  def drag_to(element)
14
- return super unless self[:draggable] == 'true'
15
-
16
- scroll_if_needed { browser_action.click_and_hold(native).perform }
17
- driver.execute_script HTML5_DRAG_DROP_SCRIPT, self, element
18
+ return super unless draggable?
19
+ html5_drag_to(element)
18
20
  end
19
21
 
20
22
  private
@@ -22,26 +24,4 @@ private
22
24
  def bridge
23
25
  driver.browser.send(:bridge)
24
26
  end
25
-
26
- HTML5_DRAG_DROP_SCRIPT = <<~JS
27
- var source = arguments[0];
28
- var target = arguments[1];
29
-
30
- var dt = new DataTransfer();
31
- var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
32
-
33
- var dragEvent = new DragEvent('dragstart', opts);
34
- source.dispatchEvent(dragEvent);
35
- target.scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'});
36
- var dragOverEvent = new DragEvent('dragover', opts);
37
- target.dispatchEvent(dragOverEvent);
38
- var dragLeaveEvent = new DragEvent('dragleave', opts);
39
- target.dispatchEvent(dragLeaveEvent);
40
- if (dragOverEvent.defaultPrevented) {
41
- var dropEvent = new DragEvent('drop', opts);
42
- target.dispatchEvent(dropEvent);
43
- }
44
- var dragEndEvent = new DragEvent('dragend', opts);
45
- source.dispatchEvent(dragEndEvent);
46
- JS
47
27
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
+ require 'capybara/selenium/extensions/html5_drag'
2
3
 
3
4
  class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node
5
+ include Html5Drag
6
+
4
7
  def click(keys = [], **options)
5
8
  super
6
9
  rescue ::Selenium::WebDriver::Error::ElementNotInteractableError
@@ -54,10 +57,8 @@ class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node
54
57
  end
55
58
 
56
59
  def drag_to(element)
57
- return super unless (browser_version >= 62.0) && (self[:draggable] == 'true')
58
-
59
- scroll_if_needed { browser_action.click_and_hold(native).perform }
60
- driver.execute_script HTML5_DRAG_DROP_SCRIPT, self, element
60
+ return super unless (browser_version >= 62.0) && draggable?
61
+ html5_drag_to(element)
61
62
  end
62
63
 
63
64
  private
@@ -116,26 +117,4 @@ private
116
117
  def browser_version
117
118
  driver.browser.capabilities[:browser_version].to_f
118
119
  end
119
-
120
- HTML5_DRAG_DROP_SCRIPT = <<~JS
121
- var source = arguments[0];
122
- var target = arguments[1];
123
-
124
- var dt = new DataTransfer();
125
- var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
126
-
127
- var dragEvent = new DragEvent('dragstart', opts);
128
- source.dispatchEvent(dragEvent);
129
- target.scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'});
130
- var dragOverEvent = new DragEvent('dragover', opts);
131
- target.dispatchEvent(dragOverEvent);
132
- var dragLeaveEvent = new DragEvent('dragleave', opts);
133
- target.dispatchEvent(dragLeaveEvent);
134
- if (dragOverEvent.defaultPrevented) {
135
- var dropEvent = new DragEvent('drop', opts);
136
- target.dispatchEvent(dropEvent);
137
- }
138
- var dragEndEvent = new DragEvent('dragend', opts);
139
- source.dispatchEvent(dragEndEvent);
140
- JS
141
120
  end
@@ -364,7 +364,7 @@ module Capybara
364
364
  # @overload switch_to_frame(element)
365
365
  # @param [Capybara::Node::Element] iframe/frame element to switch to
366
366
  # @overload switch_to_frame(:parent)
367
- # Switch to the parent element
367
+ # Switch to the parent frame
368
368
  # @overload switch_to_frame(:top)
369
369
  # Switch to the top level document
370
370
  #
@@ -1,7 +1,7 @@
1
1
  var activeRequests = 0;
2
2
  $(function() {
3
3
  $('#change').text('I changed it');
4
- $('#drag, #drag_scroll').draggable();
4
+ $('#drag, #drag_scroll, #drag_link').draggable();
5
5
  $('#drop, #drop_scroll').droppable({
6
6
  drop: function(event, ui) {
7
7
  ui.draggable.remove();
@@ -22,4 +22,10 @@ Capybara::SpecHelper.spec '#match_css?' do
22
22
  expect(@element).to match_css('span') { |el| el[:class] == 'number' }
23
23
  expect(@element).not_to match_css('span') { |el| el[:class] == 'not_number' }
24
24
  end
25
+
26
+ it 'should work with root element found via ancestor' do
27
+ el = @session.find(:css, 'body').find(:xpath, '..')
28
+ expect(el).to match_css('html')
29
+ expect { expect(el).to not_match_css('html') }.to raise_exception(RSpec::Expectations::ExpectationNotMetError)
30
+ end
25
31
  end
@@ -316,6 +316,14 @@ Capybara::SpecHelper.spec 'node' do
316
316
  element.drag_to(target)
317
317
  expect(@session).to have_xpath('//div[contains(., "Dropped!")]')
318
318
  end
319
+
320
+ it 'should drag a link' do
321
+ @session.visit('/with_js')
322
+ link = @session.find_link('drag_link')
323
+ target = @session.find(:id, 'drop')
324
+ link.drag_to target
325
+ expect(@session).to have_xpath('//div[contains(., "Dropped!")]')
326
+ end
319
327
  end
320
328
 
321
329
  describe '#hover', requires: [:hover] do
@@ -12,6 +12,7 @@
12
12
  <h1>FooBar</h1>
13
13
 
14
14
  <p id="change">This is text</p>
15
+ <a id="drag_link" href='#'>This link is non-HTML5 draggable</a>
15
16
  <div id="drag">
16
17
  <p>This is a draggable element.</p>
17
18
  </div>
@@ -27,6 +28,7 @@
27
28
  <div id="drag_html5" draggable="true">
28
29
  <p>This is an HTML5 draggable element.</p>
29
30
  </div>
31
+ <a id="drag_link_html5" href="#">This is an HTML5 draggable link</a>
30
32
  <div id="drop_html5" class="drop">
31
33
  <p>It should be dropped here.</p>
32
34
  </div>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.7.1'
4
+ VERSION = '3.7.2'
5
5
  end
@@ -313,6 +313,15 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
313
313
  element.drag_to(target)
314
314
  expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5_scroll")]')
315
315
  end
316
+
317
+ it 'should drag HTML5 default draggable elements' do
318
+ pending "Firefox < 62 doesn't support a DataTransfer constuctor" if marionette_lt?(62.0, session)
319
+ session.visit('/with_js')
320
+ link = session.find_link('drag_link_html5')
321
+ target = session.find(:id, 'drop_html5')
322
+ link.drag_to target
323
+ expect(session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
324
+ end
316
325
  end
317
326
 
318
327
  context 'Windows' do
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.7.1
4
+ version: 3.7.2
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: 2018-09-05 00:00:00.000000000 Z
13
+ date: 2018-09-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: addressable
@@ -311,6 +311,7 @@ files:
311
311
  - lib/capybara/selenium/driver.rb
312
312
  - lib/capybara/selenium/driver_specializations/chrome_driver.rb
313
313
  - lib/capybara/selenium/driver_specializations/marionette_driver.rb
314
+ - lib/capybara/selenium/extensions/html5_drag.rb
314
315
  - lib/capybara/selenium/node.rb
315
316
  - lib/capybara/selenium/nodes/chrome_node.rb
316
317
  - lib/capybara/selenium/nodes/marionette_node.rb