Skip to content

Commit c31bd84

Browse files
authored
Merge pull request #778 from seleniumbase/drag-and-drop-with-offset
Improve drag-and-drop functionality
2 parents 09ea75b + 2e0ba79 commit c31bd84

File tree

6 files changed

+71
-3
lines changed

6 files changed

+71
-3
lines changed

help_docs/method_summary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ self.drag_and_drop(drag_selector, drop_selector,
131131
drag_by=By.CSS_SELECTOR, drop_by=By.CSS_SELECTOR,
132132
timeout=None)
133133

134+
self.drag_and_drop_with_offset(selector, x, y, by=By.CSS_SELECTOR, timeout=None)
135+
134136
self.select_option_by_text(dropdown_selector, option,
135137
dropdown_by=By.CSS_SELECTOR,
136138
timeout=None)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pip>=20.3.3
22
packaging>=20.8
33
setuptools>=44.1.1;python_version<"3.5"
44
setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"
5-
setuptools>=51.1.1;python_version>="3.6"
5+
setuptools>=51.1.2;python_version>="3.6"
66
setuptools-scm>=5.0.1
77
wheel>=0.36.2
88
attrs>=20.3.0

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "1.51.12"
2+
__version__ = "1.51.13"

seleniumbase/fixtures/base_case.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,28 @@ def drag_and_drop(self, drag_selector, drop_selector,
14741474
self.__slow_mode_pause_if_active()
14751475
return drag_element
14761476

1477+
def drag_and_drop_with_offset(
1478+
self, selector, x, y, by=By.CSS_SELECTOR, timeout=None):
1479+
""" Drag and drop an element to an {X,Y}-offset location. """
1480+
if not timeout:
1481+
timeout = settings.SMALL_TIMEOUT
1482+
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
1483+
timeout = self.__get_new_timeout(timeout)
1484+
selector, by = self.__recalculate_selector(selector, by)
1485+
css_selector = self.convert_to_css_selector(selector, by=by)
1486+
element = self.wait_for_element_visible(css_selector, timeout=timeout)
1487+
self.__demo_mode_highlight_if_active(css_selector, By.CSS_SELECTOR)
1488+
css_selector = re.escape(css_selector) # Add "\\" to special chars
1489+
css_selector = self.__escape_quotes_if_needed(css_selector)
1490+
script = js_utils.get_drag_and_drop_with_offset_script(
1491+
css_selector, x, y)
1492+
self.safe_execute_script(script)
1493+
if self.demo_mode:
1494+
self.__demo_mode_pause_if_active()
1495+
elif self.slow_mode:
1496+
self.__slow_mode_pause_if_active()
1497+
return element
1498+
14771499
def __select_option(self, dropdown_selector, option,
14781500
dropdown_by=By.CSS_SELECTOR, option_by="text",
14791501
timeout=None):

seleniumbase/fixtures/js_utils.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,50 @@ def get_drag_and_drop_script():
792792
return script
793793

794794

795+
def get_drag_and_drop_with_offset_script(selector, x, y):
796+
script_a = (
797+
"""
798+
var source = document.querySelector("%s");
799+
var offsetX = %f;
800+
var offsetY = %f;
801+
""" % (selector, x, y))
802+
script_b = (
803+
r"""
804+
var rect = source.getBoundingClientRect();
805+
var dragPt = {x: rect.left + (rect.width >> 1),
806+
y: rect.top + (rect.height >> 1)};
807+
var dropPt = {x: dragPt.x + offsetX, y: dragPt.y + offsetY};
808+
var target = document.elementFromPoint(dropPt.x, dropPt.y);
809+
var dataTransfer = {
810+
dropEffect: '',
811+
effectAllowed: 'all',
812+
files: [],
813+
items: {},
814+
types: [],
815+
setData: function (format, data) {
816+
this.items[format] = data;
817+
this.types.push(format);
818+
},
819+
getData: function (format) {
820+
return this.items[format];
821+
},
822+
clearData: function (format) { }
823+
};
824+
var emit = function (event, target, pt) {
825+
var evt = document.createEvent('MouseEvent');
826+
evt.initMouseEvent(event, true, true, window, 0, 0, 0, pt.x, pt.y,
827+
false, false, false, false, 0, null);
828+
evt.dataTransfer = dataTransfer;
829+
target.dispatchEvent(evt);
830+
};
831+
emit('mousedown', source, dragPt);
832+
emit('mousemove', source, dragPt);
833+
emit('mousemove', source, dropPt);
834+
emit('mouseup', source, dropPt);""")
835+
script = script_a + script_b
836+
return script
837+
838+
795839
def clear_out_console_logs(driver):
796840
try:
797841
# Clear out the current page log before navigating to a new page

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
'packaging>=20.8',
107107
'setuptools>=44.1.1;python_version<"3.5"',
108108
'setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"',
109-
'setuptools>=51.1.1;python_version>="3.6"',
109+
'setuptools>=51.1.2;python_version>="3.6"',
110110
'setuptools-scm>=5.0.1',
111111
'wheel>=0.36.2',
112112
'attrs>=20.3.0',

0 commit comments

Comments
 (0)