Skip to content

Commit fafde7e

Browse files
committed
Add a drag_and_drop() method
1 parent 59fb5c1 commit fafde7e

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

help_docs/method_summary.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ self.hover_and_double_click(hover_selector, click_selector,
123123
hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR,
124124
timeout=None)
125125

126+
self.drag_and_drop(drag_selector, drop_selector,
127+
drag_by=By.CSS_SELECTOR, drop_by=By.CSS_SELECTOR,
128+
timeout=None)
129+
126130
self.select_option_by_text(dropdown_selector, option,
127131
dropdown_by=By.CSS_SELECTOR,
128132
timeout=None)

seleniumbase/fixtures/base_case.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,41 @@ def hover_and_double_click(self, hover_selector, click_selector,
12911291
self.__slow_mode_pause_if_active()
12921292
return element
12931293

1294+
def drag_and_drop(self, drag_selector, drop_selector,
1295+
drag_by=By.CSS_SELECTOR, drop_by=By.CSS_SELECTOR,
1296+
timeout=None):
1297+
""" Drag and drop an element from one selector to another. """
1298+
if not timeout:
1299+
timeout = settings.SMALL_TIMEOUT
1300+
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
1301+
timeout = self.__get_new_timeout(timeout)
1302+
drag_selector, drag_by = self.__recalculate_selector(
1303+
drag_selector, drag_by)
1304+
drop_selector, drop_by = self.__recalculate_selector(
1305+
drop_selector, drop_by)
1306+
drag_element = self.wait_for_element_visible(
1307+
drag_selector, by=drag_by, timeout=timeout)
1308+
self.__demo_mode_highlight_if_active(drag_selector, drag_by)
1309+
self.wait_for_element_visible(
1310+
drop_selector, by=drop_by, timeout=timeout)
1311+
self.__demo_mode_highlight_if_active(drop_selector, drop_by)
1312+
self.scroll_to(drag_selector, by=drag_by)
1313+
drag_selector = self.convert_to_css_selector(
1314+
drag_selector, drag_by)
1315+
drop_selector = self.convert_to_css_selector(
1316+
drop_selector, drop_by)
1317+
drag_and_drop_script = js_utils.get_drag_and_drop_script()
1318+
self.safe_execute_script(
1319+
drag_and_drop_script + (
1320+
"$('%s').simulateDragDrop("
1321+
"{dropTarget: "
1322+
"'%s'});" % (drag_selector, drop_selector)))
1323+
if self.demo_mode:
1324+
self.__demo_mode_pause_if_active()
1325+
elif self.slow_mode:
1326+
self.__slow_mode_pause_if_active()
1327+
return drag_element
1328+
12941329
def __select_option(self, dropdown_selector, option,
12951330
dropdown_by=By.CSS_SELECTOR, option_by="text",
12961331
timeout=None):

seleniumbase/fixtures/js_utils.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,64 @@ def slow_scroll_to_element(driver, element, browser):
732732
time.sleep(0.162)
733733

734734

735+
def get_drag_and_drop_script():
736+
script = (r"""(function( $ ) {
737+
$.fn.simulateDragDrop = function(options) {
738+
return this.each(function() {
739+
new $.simulateDragDrop(this, options);
740+
});
741+
};
742+
$.simulateDragDrop = function(elem, options) {
743+
this.options = options;
744+
this.simulateEvent(elem, options);
745+
};
746+
$.extend($.simulateDragDrop.prototype, {
747+
simulateEvent: function(elem, options) {
748+
/*Simulating drag start*/
749+
var type = 'dragstart';
750+
var event = this.createEvent(type);
751+
this.dispatchEvent(elem, type, event);
752+
753+
/*Simulating drop*/
754+
type = 'drop';
755+
var dropEvent = this.createEvent(type, {});
756+
dropEvent.dataTransfer = event.dataTransfer;
757+
this.dispatchEvent(
758+
$(options.dropTarget)[0], type, dropEvent);
759+
760+
/*Simulating drag end*/
761+
type = 'dragend';
762+
var dragEndEvent = this.createEvent(type, {});
763+
dragEndEvent.dataTransfer = event.dataTransfer;
764+
this.dispatchEvent(elem, type, dragEndEvent);
765+
},
766+
createEvent: function(type) {
767+
var event = document.createEvent("CustomEvent");
768+
event.initCustomEvent(type, true, true, null);
769+
event.dataTransfer = {
770+
data: {
771+
},
772+
setData: function(type, val){
773+
this.data[type] = val;
774+
},
775+
getData: function(type){
776+
return this.data[type];
777+
}
778+
};
779+
return event;
780+
},
781+
dispatchEvent: function(elem, type, event) {
782+
if(elem.dispatchEvent) {
783+
elem.dispatchEvent(event);
784+
}else if( elem.fireEvent ) {
785+
elem.fireEvent("on"+type, event);
786+
}
787+
}
788+
});
789+
})(jQuery);""")
790+
return script
791+
792+
735793
@decorators.deprecated("Use re.escape() instead, which does what you want!")
736794
def _jq_format(code):
737795
"""

0 commit comments

Comments
 (0)