mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
HTML5 draggable elements shold be draggable from their children
This commit is contained in:
parent
c053ff60de
commit
b9d1b8f3a4
4 changed files with 35 additions and 5 deletions
|
@ -7,8 +7,8 @@ class Capybara::Selenium::Node
|
||||||
def drag_to(element, delay: 0.05)
|
def drag_to(element, delay: 0.05)
|
||||||
driver.execute_script MOUSEDOWN_TRACKER
|
driver.execute_script MOUSEDOWN_TRACKER
|
||||||
scroll_if_needed { browser_action.click_and_hold(native).perform }
|
scroll_if_needed { browser_action.click_and_hold(native).perform }
|
||||||
if driver.evaluate_script('window.capybara_mousedown_prevented || !arguments[0].draggable', self)
|
if driver.evaluate_script(LEGACY_DRAG_CHECK, self)
|
||||||
perform_regular_drag(element)
|
perform_legacy_drag(element)
|
||||||
else
|
else
|
||||||
perform_html5_drag(element, delay)
|
perform_html5_drag(element, delay)
|
||||||
end
|
end
|
||||||
|
@ -16,7 +16,7 @@ class Capybara::Selenium::Node
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def perform_regular_drag(element)
|
def perform_legacy_drag(element)
|
||||||
element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
|
element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,6 +94,16 @@ class Capybara::Selenium::Node
|
||||||
}, { once: true, passive: true })
|
}, { once: true, passive: true })
|
||||||
JS
|
JS
|
||||||
|
|
||||||
|
LEGACY_DRAG_CHECK = <<~JS
|
||||||
|
(function(el){
|
||||||
|
if (window.capybara_mousedown_prevented) return true;
|
||||||
|
do {
|
||||||
|
if (el.draggable) return false;
|
||||||
|
} while (el = el.parentElement );
|
||||||
|
return true;
|
||||||
|
})(arguments[0])
|
||||||
|
JS
|
||||||
|
|
||||||
HTML5_DRAG_DROP_SCRIPT = <<~JS
|
HTML5_DRAG_DROP_SCRIPT = <<~JS
|
||||||
function rectCenter(rect){
|
function rectCenter(rect){
|
||||||
return new DOMPoint(
|
return new DOMPoint(
|
||||||
|
@ -174,6 +184,10 @@ class Capybara::Selenium::Node
|
||||||
var dt = new DataTransfer();
|
var dt = new DataTransfer();
|
||||||
var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
|
var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
|
||||||
|
|
||||||
|
while (source && !source.draggable) {
|
||||||
|
source = source.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
if (source.tagName == 'A'){
|
if (source.tagName == 'A'){
|
||||||
dt.setData('text/uri-list', source.href);
|
dt.setData('text/uri-list', source.href);
|
||||||
dt.setData('text', source.href);
|
dt.setData('text', source.href);
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def perform_regular_drag(element)
|
def perform_legacy_drag(element)
|
||||||
return super unless (browser_version < 77.0) && w3c? && !element.obscured?
|
return super unless (browser_version < 77.0) && w3c? && !element.obscured?
|
||||||
|
|
||||||
# W3C Chrome/chromedriver < 77 doesn't maintain mouse button state across actions API performs
|
# W3C Chrome/chromedriver < 77 doesn't maintain mouse button state across actions API performs
|
||||||
|
|
|
@ -438,6 +438,14 @@ Capybara::SpecHelper.spec 'node' do
|
||||||
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should HTML5 drag and drop an object child' do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
element = @session.find('//div[@id="drag_html5"]/p')
|
||||||
|
target = @session.find('//div[@id="drop_html5"]')
|
||||||
|
element.drag_to(target)
|
||||||
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should set clientX/Y in dragover events' do
|
it 'should set clientX/Y in dragover events' do
|
||||||
@session.visit('/with_js')
|
@session.visit('/with_js')
|
||||||
element = @session.find('//div[@id="drag_html5"]')
|
element = @session.find('//div[@id="drag_html5"]')
|
||||||
|
@ -481,6 +489,14 @@ Capybara::SpecHelper.spec 'node' do
|
||||||
expect(@session).to have_content(/Item 3.*Item 1/, normalize_ws: true)
|
expect(@session).to have_content(/Item 3.*Item 1/, normalize_ws: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should drag HTML5 default draggable element child' do
|
||||||
|
@session.visit('/with_js')
|
||||||
|
source = @session.find_link('drag_link_html5').find(:css, 'p')
|
||||||
|
target = @session.find(:id, 'drop_html5')
|
||||||
|
source.drag_to target
|
||||||
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<div id="drag_html5" draggable="true">
|
<div id="drag_html5" draggable="true">
|
||||||
<p>This is an HTML5 draggable element.</p>
|
<p>This is an HTML5 draggable element.</p>
|
||||||
</div>
|
</div>
|
||||||
<a id="drag_link_html5" href="#">This is an HTML5 draggable link</a>
|
<a id="drag_link_html5" href="#"><p>This is an HTML5 draggable link</p></a>
|
||||||
<div id="drop_html5" class="drop">
|
<div id="drop_html5" class="drop">
|
||||||
<p>It should be dropped here.</p>
|
<p>It should be dropped here.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue