Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/cdp_mode/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,10 @@ sb.click_if_visible(selector, timeout=0, scroll=True)
sb.click_visible_elements(selector, limit=0, scroll=True)
sb.click_nth_element(selector, number, scroll=True)
sb.click_nth_visible_element(selector, number, scroll=True)
sb.click_link(link_text)
sb.click_with_offset(selector, x, y, center=False, scroll=True)
sb.click_and_hold(selector, timeout=None, scroll=True, timeframe=2)
sb.click_link(link_text)
sb.drag_and_drop(drag_selector, drop_selector, timeout=None, scroll=True)
sb.go_back()
sb.go_forward()
sb.get_navigation_history()
Expand Down
8 changes: 4 additions & 4 deletions examples/cdp_mode/raw_cdp_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
sb.set_value("input#mySlider", "100")
sb.click_visible_elements("input.checkBoxClassB")
sb.select_option_by_text("#mySelect", "Set to 75%")
sb.gui_hover_and_click("#myDropdown", "#dropOption2")
sb.gui_click_element("#checkBox1")
sb.gui_drag_and_drop("img#logo", "div#drop2")
sb.hover_and_click("#myDropdown", "#dropOption2")
sb.click("#checkBox1")
sb.drag_and_drop("img#logo", "div#drop2")
sb.nested_click("iframe#myFrame3", ".fBox")
sb.sleep(2)
sb.sleep(1)
sb.quit()
8 changes: 4 additions & 4 deletions examples/cdp_mode/raw_cdp_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
sb.set_value("input#mySlider", "100")
sb.click_visible_elements("input.checkBoxClassB")
sb.select_option_by_text("#mySelect", "Set to 75%")
sb.gui_hover_and_click("#myDropdown", "#dropOption2")
sb.gui_click_element("#checkBox1")
sb.gui_drag_and_drop("img#logo", "div#drop2")
sb.hover_and_click("#myDropdown", "#dropOption2")
sb.click("#checkBox1")
sb.drag_and_drop("img#logo", "div#drop2")
sb.nested_click("iframe#myFrame3", ".fBox")
sb.sleep(2)
sb.sleep(1)
sb.quit()
2 changes: 1 addition & 1 deletion examples/cdp_mode/raw_demo_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

# Verify Drag and Drop
sb.assert_element_not_visible("div#drop2 img#logo")
sb.gui_drag_and_drop("img#logo", "div#drop2")
sb.drag_and_drop("img#logo", "div#drop2")
sb.assert_element("div#drop2 img#logo")

# Click inside an iframe and test highlighting
Expand Down
2 changes: 1 addition & 1 deletion examples/cdp_mode/raw_drag_and_drop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
sb.activate_cdp_mode()
sb.goto("https://seleniumbase.io/other/drag_and_drop")
sb.assert_element_not_visible("#div1 img#drag1")
sb.gui_drag_and_drop("#drag1", "#div1")
sb.drag_and_drop("#drag1", "#div1")
sb.assert_element("#div1 img#drag1")
sb.sleep(1)

Expand Down
3 changes: 2 additions & 1 deletion help_docs/cdp_mode_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ sb.click_if_visible(selector, timeout=0, scroll=True)
sb.click_visible_elements(selector, limit=0, scroll=True)
sb.click_nth_element(selector, number, scroll=True)
sb.click_nth_visible_element(selector, number, scroll=True)
sb.click_link(link_text)
sb.click_with_offset(selector, x, y, center=False, scroll=True)
sb.click_and_hold(selector, timeout=None, scroll=True, timeframe=2)
sb.click_link(link_text)
sb.drag_and_drop(drag_selector, drop_selector, timeout=None, scroll=True)
sb.go_back()
sb.go_forward()
sb.get_navigation_history()
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.51.7"
__version__ = "4.51.8"
1 change: 1 addition & 0 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
cdp.click_visible_elements = CDPM.click_visible_elements
cdp.click_with_offset = CDPM.click_with_offset
cdp.click_and_hold = CDPM.click_and_hold
cdp.drag_and_drop = CDPM.drag_and_drop
cdp.mouse_click = CDPM.mouse_click
cdp.get_parent = CDPM.get_parent
cdp.remove_element = CDPM.remove_element
Expand Down
126 changes: 126 additions & 0 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,132 @@ def click_and_hold(self, selector, timeout=None, scroll=True, timeframe=2):
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait(0.2))

def drag_and_drop(
self, drag_selector, drop_selector, timeout=None, scroll=True,
):
"""(Simulate a mouse drag & drop)"""
if not timeout:
timeout = settings.SMALL_TIMEOUT
self.__slow_mode_pause_if_set()
self.find_element(drag_selector, timeout=timeout)
drop_target = self.find_element(drop_selector, timeout=timeout)
if scroll:
drop_target.scroll_into_view()
script = f"""(() => {{
var e = document.querySelector("{drag_selector}"),
n = document.querySelector("{drop_selector}"),
i = 0, o = 0, r = 1,
a = '',
s = 'alt' === a || '\ue00a' === a,
l = 'ctrl' === a || '\ue009' === a,
c = 'shift' === a || '\ue008' === a,
u = e.ownerDocument,
f = e.getBoundingClientRect(),
g = n ? n.getBoundingClientRect() : f,
p = f.left + f.width / 2,
d = f.top + f.height / 2,
h = g.left + (i || g.width / 2),
m = g.top + (o || g.height / 2),
v = u.elementFromPoint(p, d),
y = u.elementFromPoint(h, m);
if (!v || !y) {{
var E = new Error(
'source or target element is not interactable');
throw E.code = 15, E;
}}
var _ = {{
constructor: DataTransfer,
effectAllowed: null,
dropEffect: null,
types: [],
files: Object.setPrototypeOf([], null),
_items: Object.setPrototypeOf([], {{
add: function(t, e) {{
this[this.length] = {{
_data: '' + t,
kind: 'string',
type: e,
getAsFile: function() {{}},
getAsString: function(t) {{ t(this._data); }}
}};
_.types.push(e);
}},
remove: function(t) {{
Array.prototype.splice.call(this, 65535 & t, 1);
_.types.splice(65535 & t, 1);
}},
clear: function(t, e) {{
this.length = 0;
_.types.length = 0;
}}
}}),
setData: function(t, e) {{
this.clearData(t); this._items.add(e, t); }},
getData: function(t) {{
for (
var e = this._items.length;
e-- && this._items[e].type !== t;);
return e >= 0 ? this._items[e]._data : null;
}},
clearData: function(t) {{
for (
var e = this._items.length;
e-- && this._items[e].type !== t;);
this._items.remove(e);
}},
setDragImage: function(t) {{}}
}};
function w(t, e, n, i) {{
for (var o = 0; o < e.length; ++o) {{
var r = u.createEvent('MouseEvent');
r.initMouseEvent(
e[o], !0, !0, u.defaultView,
0, 0, 0, p, d, l, s, c, !1, 0, null);
t.dispatchEvent(r);
}}
i && setTimeout(i, n);
}}
function D(t, e, n, i) {{
var o = u.createEvent('DragEvent');
o.initMouseEvent(
e, !0, !0, u.defaultView, 0, 0,
0, p, d, l, s, c, !1, 0, null);
Object.setPrototypeOf(o, null);
o.dataTransfer = _;
Object.setPrototypeOf(o, DragEvent.prototype);
t.dispatchEvent(o);
i && setTimeout(i, n);
}}
'items' in DataTransfer.prototype && (_.items = _._items);
w(v, ['pointerdown', 'mousedown'], 1, function() {{
for (var t = v; t && !t.draggable;) t = t.parentElement;
if (t && t.contains(v)) {{
var e = y.getBoundingClientRect();
D(v, 'dragstart', r, function() {{
var t = y.getBoundingClientRect();
p = t.left + h - e.left;
d = t.top + m - e.top;
D(y, 'dragenter', 1, function() {{
D(y, 'dragover', r, function() {{
D(
u.elementFromPoint(p, d),
'drop', 1, function() {{
D(v, 'dragend', 1, function() {{
w(
u.elementFromPoint(p, d),
['mouseup', 'pointerup']);
}});
}});
}});
}});
}});
}}
}});
}})();"""
self.evaluate(script)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait(0.2))

def mouse_click(self, selector, timeout=None, scroll=True):
"""(Simulate a mouse click)"""
if not timeout:
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -2998,7 +2998,7 @@ def drag_and_drop(
drop_selector, drop_by
)
if self.__is_cdp_swap_needed():
self.cdp.gui_drag_and_drop(drag_selector, drop_selector)
self.cdp.drag_and_drop(drag_selector, drop_selector)
return
drag_element = self.wait_for_element_clickable(
drag_selector, by=drag_by, timeout=timeout
Expand Down