Skip to content

Commit fe08a93

Browse files
authored
Merge pull request #633 from seleniumbase/drag-and-drop
Add a drag_and_drop() method
2 parents 59fb5c1 + afdb1f7 commit fe08a93

File tree

9 files changed

+149
-25
lines changed

9 files changed

+149
-25
lines changed

examples/test_drag_and_drop.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Testing Drag & Drop
3+
"""
4+
5+
from seleniumbase import BaseCase
6+
7+
8+
class DragAndDropTests(BaseCase):
9+
10+
def test_drag_and_drop(self):
11+
self.open('https://www.w3schools.com/html/html5_draganddrop.asp')
12+
self.remove_elements("script") # Ad content slows down the page
13+
self.remove_elements("iframe") # Ad content slows down the page
14+
self.scroll_to("#div1")
15+
self.sleep(0.5)
16+
self.assert_false(self.is_element_visible("#div2 img#drag1"))
17+
self.drag_and_drop("#div1 img#drag1", '#div2')
18+
self.assert_true(self.is_element_visible("#div2 img#drag1"))
19+
self.sleep(1)

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)

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ parameterized==0.7.4
3232
soupsieve==1.9.6;python_version<"3.5"
3333
soupsieve==2.0.1;python_version>="3.5"
3434
beautifulsoup4==4.9.1
35-
cryptography==2.9.2
35+
cryptography==3.0
3636
pyopenssl==19.1.0
3737
pygments==2.5.2;python_version<"3.5"
3838
pygments==2.6.1;python_version>="3.5"
@@ -51,4 +51,4 @@ pyflakes==2.2.0;python_version>="3.5"
5151
certifi>=2020.6.20
5252
allure-pytest==2.8.16
5353
pdfminer.six==20191110;python_version<"3.5"
54-
pdfminer.six==20200517;python_version>="3.5"
54+
pdfminer.six==20200720;python_version>="3.5"

seleniumbase/config/ad_block_list.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717
"""
1818

1919
AD_BLOCK_LIST = [
20-
'script[src*="/adservice."]',
21-
'script[src*="doubleclick.net"]',
22-
'script[src*="googletagservices.com"]',
23-
'script[src*="doubleclick.net"]',
24-
'script[src*="adsbygoogle.js"]',
25-
'script[src*="adroll.com"]',
26-
'script[src*="/pagead/"]',
27-
'script[src*="ads-host"]',
28-
'script[src*="adsystem.com"]',
29-
'script[type="data-doubleclick"]',
20+
'[src*="/adservice."]',
21+
'[src*="doubleclick.net"]',
22+
'[src*="googletagservices.com"]',
23+
'[src*="adsbygoogle.js"]',
24+
'[src*="adroll.com"]',
25+
'[src*="/pagead/"]',
26+
'[type="data-doubleclick"]',
27+
'iframe[data-google-container-id]',
3028
'iframe[src*="doubleclick.net"]',
29+
'iframe[src*="/AdServer/"]',
30+
'iframe[src*="openx.net"]',
3131
'iframe[onload*="doWithAds"]',
3232
'iframe[id*="google_ads_frame"]',
3333
'[aria-label="Ad"]',

seleniumbase/config/proxy_list.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
"""
2121

2222
PROXY_LIST = {
23-
"example1": "104.154.143.77:3128", # (Example) - set your own proxy here
23+
"example1": "82.200.233.4:3128", # (Example) - set your own proxy here
2424
"example2": "105.112.8.53:3128", # (Example) - set your own proxy here
25-
"example3": "82.200.233.4:3128", # (Example) - set your own proxy here
26-
"example4": "176.53.40.222:3128", # (Example) - set your own proxy here
2725
"proxy1": None,
2826
"proxy2": None,
2927
"proxy3": None,

seleniumbase/core/browser_launcher.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,22 @@ def _set_chrome_options(
175175
chrome_options.add_experimental_option(
176176
"mobileEmulation", emulator_settings)
177177
chrome_options.add_argument("--enable-sync")
178-
if incognito:
179-
chrome_options.add_argument("--incognito")
180-
elif guest_mode:
181-
chrome_options.add_argument("--guest")
182-
else:
183-
pass
178+
if not proxy_auth and not disable_csp and (
179+
not extension_zip and not extension_dir):
180+
if incognito:
181+
# Use Chrome's Incognito Mode
182+
# Incognito Mode prevents Chrome extensions from loading,
183+
# so if using extensions or a feature that uses extensions,
184+
# then Chrome's Incognito mode will be disabled instead.
185+
chrome_options.add_argument("--incognito")
186+
elif guest_mode:
187+
# Use Chrome's Guest Mode
188+
# Guest mode prevents Chrome extensions from loading,
189+
# so if using extensions or a feature that uses extensions,
190+
# then Chrome's Guest Mode will be disabled instead.
191+
chrome_options.add_argument("--guest")
192+
else:
193+
pass
184194
if user_data_dir:
185195
abs_path = os.path.abspath(user_data_dir)
186196
chrome_options.add_argument("user-data-dir=%s" % abs_path)

seleniumbase/fixtures/base_case.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,7 @@ def hover_and_double_click(self, hover_selector, click_selector,
12561256
hover_selector, hover_by)
12571257
hover_selector = self.convert_to_css_selector(
12581258
hover_selector, hover_by)
1259+
hover_by = By.CSS_SELECTOR
12591260
click_selector, click_by = self.__recalculate_selector(
12601261
click_selector, click_by)
12611262
dropdown_element = self.wait_for_element_visible(
@@ -1291,6 +1292,41 @@ def hover_and_double_click(self, hover_selector, click_selector,
12911292
self.__slow_mode_pause_if_active()
12921293
return element
12931294

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

23042340
def ad_block(self):
23052341
""" Block ads that appear on the current web page. """
2306-
self.wait_for_ready_state_complete()
23072342
from seleniumbase.config import ad_block_list
23082343
for css_selector in ad_block_list.AD_BLOCK_LIST:
23092344
css_selector = re.escape(css_selector)

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
"""

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
setup(
5656
name='seleniumbase',
57-
version='1.42.15',
57+
version='1.43.0',
5858
description='Fast, Easy, and Reliable Browser Automation & Testing.',
5959
long_description=long_description,
6060
long_description_content_type='text/markdown',
@@ -124,7 +124,7 @@
124124
'soupsieve==1.9.6;python_version<"3.5"',
125125
'soupsieve==2.0.1;python_version>="3.5"',
126126
'beautifulsoup4==4.9.1',
127-
'cryptography==2.9.2',
127+
'cryptography==3.0',
128128
'pyopenssl==19.1.0',
129129
'pygments==2.5.2;python_version<"3.5"',
130130
'pygments==2.6.1;python_version>="3.5"',
@@ -143,7 +143,7 @@
143143
'certifi>=2020.6.20',
144144
'allure-pytest==2.8.16',
145145
'pdfminer.six==20191110;python_version<"3.5"',
146-
'pdfminer.six==20200517;python_version>="3.5"',
146+
'pdfminer.six==20200720;python_version>="3.5"',
147147
],
148148
packages=[
149149
'seleniumbase',

0 commit comments

Comments
 (0)