HTML5 draggable elements shold be draggable from their children
This commit is contained in:
parent
c053ff60de
commit
b9d1b8f3a4
|
@ -7,8 +7,8 @@ class Capybara::Selenium::Node
|
|||
def drag_to(element, delay: 0.05)
|
||||
driver.execute_script MOUSEDOWN_TRACKER
|
||||
scroll_if_needed { browser_action.click_and_hold(native).perform }
|
||||
if driver.evaluate_script('window.capybara_mousedown_prevented || !arguments[0].draggable', self)
|
||||
perform_regular_drag(element)
|
||||
if driver.evaluate_script(LEGACY_DRAG_CHECK, self)
|
||||
perform_legacy_drag(element)
|
||||
else
|
||||
perform_html5_drag(element, delay)
|
||||
end
|
||||
|
@ -16,7 +16,7 @@ class Capybara::Selenium::Node
|
|||
|
||||
private
|
||||
|
||||
def perform_regular_drag(element)
|
||||
def perform_legacy_drag(element)
|
||||
element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
|
||||
end
|
||||
|
||||
|
@ -94,6 +94,16 @@ class Capybara::Selenium::Node
|
|||
}, { once: true, passive: true })
|
||||
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
|
||||
function rectCenter(rect){
|
||||
return new DOMPoint(
|
||||
|
@ -174,6 +184,10 @@ class Capybara::Selenium::Node
|
|||
var dt = new DataTransfer();
|
||||
var opts = { cancelable: true, bubbles: true, dataTransfer: dt };
|
||||
|
||||
while (source && !source.draggable) {
|
||||
source = source.parentElement;
|
||||
}
|
||||
|
||||
if (source.tagName == 'A'){
|
||||
dt.setData('text/uri-list', source.href);
|
||||
dt.setData('text', source.href);
|
||||
|
|
|
@ -57,7 +57,7 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
|
|||
|
||||
private
|
||||
|
||||
def perform_regular_drag(element)
|
||||
def perform_legacy_drag(element)
|
||||
return super unless (browser_version < 77.0) && w3c? && !element.obscured?
|
||||
|
||||
# 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")]')
|
||||
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
|
||||
@session.visit('/with_js')
|
||||
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)
|
||||
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
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<div id="drag_html5" draggable="true">
|
||||
<p>This is an HTML5 draggable element.</p>
|
||||
</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">
|
||||
<p>It should be dropped here.</p>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue