Skip to content

Commit 5b5be33

Browse files
authored
Merge pull request #1403 from seleniumbase/more-js-less-jquery
More JS. Less jQuery.
2 parents 52947ad + 68416e5 commit 5b5be33

File tree

9 files changed

+100
-32
lines changed

9 files changed

+100
-32
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta property="og:image" content="https://seleniumbase.io/cdn/img/mac_sb_logo_5.png" />
66
<link rel="icon" href="https://seleniumbase.io/img/green_logo2.png" />
77

8-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/sb_logo_gs7.png" alt="SeleniumBase" title="SeleniumBase" width="275" /></a></p>
8+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/sb_logo_gs8.png" alt="SeleniumBase" title="SeleniumBase" width="275" /></a></p>
99
<p align="center"><b>Powerful end-to-end testing with <a href="https://www.selenium.dev/documentation/">Selenium</a>, <a href="https://www.python.org/about/">Python</a>, and <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>.</b></p>
1010

1111
<p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/releases" target="_blank"><img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=22AAEE" alt="GitHub version" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="SeleniumBase" /></a></p>

help_docs/method_summary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ self.hover_and_double_click(
163163

164164
self.drag_and_drop(drag_selector, drop_selector,
165165
drag_by="css selector", drop_by="css selector",
166-
timeout=None)
166+
timeout=None, jquery=False)
167167

168168
self.drag_and_drop_with_offset(
169169
selector, x, y, by="css selector", timeout=None)

mkdocs_build/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# mkdocs dependencies for generating the seleniumbase.io website
22
# Minimum Python version: 3.7
33

4-
regex>=2022.6.2
4+
regex>=2022.7.9
55
tqdm>=4.64.0
66
docutils==0.19
77
python-dateutil==2.8.2

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Pillow==9.2.0;python_version>="3.7"
130130
typing-extensions==3.10.0.2;python_version<"3.6"
131131
typing-extensions==4.1.1;python_version>="3.6" and python_version<"3.7"
132132
typing-extensions==4.2.0;python_version>="3.7" and python_version<"3.9"
133-
rich==12.4.4;python_version>="3.6" and python_version<"4.0"
133+
rich==12.5.1;python_version>="3.6" and python_version<"4.0"
134134
tornado==5.1.1;python_version<"3.5"
135135
tornado==6.1;python_version>="3.5" and python_version<"3.7"
136136
tornado==6.2;python_version>="3.7"

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__ = "3.4.0"
2+
__version__ = "3.4.1"

seleniumbase/console_scripts/sb_install.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ def requests_get(url):
107107
return response
108108

109109

110+
def requests_get_with_retry(url):
111+
response = None
112+
try:
113+
response = requests.get(url)
114+
except Exception:
115+
import time
116+
117+
time.sleep(0.75)
118+
response = requests.get(url)
119+
return response
120+
121+
110122
def main(override=None):
111123
if override:
112124
if override == "chromedriver":
@@ -344,7 +356,7 @@ def main(override=None):
344356
else:
345357
invalid_run_command()
346358
if get_latest:
347-
url_request = requests.get(last)
359+
url_request = requests_get_with_retry(last)
348360
if url_request.ok:
349361
use_version = url_request.text.split("\r")[0].split("\n")[0]
350362
use_version = use_version.split(".")[0]
@@ -370,15 +382,15 @@ def main(override=None):
370382
if use_version.isdigit():
371383
edgedriver_st = "https://msedgedriver.azureedge.net/LATEST_RELEASE"
372384
use_version = "%s_%s_%s" % (edgedriver_st, use_version, suffix)
373-
url_request = requests.get(use_version)
385+
url_request = requests_get_with_retry(use_version)
374386
if url_request.ok:
375387
use_version = url_request.text.split("\r")[0].split("\n")[0]
376388
download_url = "https://msedgedriver.azureedge.net/%s/%s" % (
377389
use_version,
378390
file_name,
379391
)
380392
if not get_latest and not use_version == DEFAULT_EDGEDRIVER_VERSION:
381-
url_request = requests.get(download_url)
393+
url_request = requests_get_with_retry(download_url)
382394
if not url_request.ok:
383395
raise Exception(
384396
"Could not find version [%s] of EdgeDriver!" % use_version
@@ -410,7 +422,7 @@ def main(override=None):
410422
"releases/download/"
411423
"%s/%s" % (headless_ie_version, headless_ie_file_name)
412424
)
413-
url_request = requests.get(headless_ie_url)
425+
url_request = requests_get_with_retry(headless_ie_url)
414426
if url_request.ok:
415427
headless_ie_exists = True
416428
msg = c2 + "HeadlessIEDriver version for download" + cr
@@ -497,7 +509,7 @@ def main(override=None):
497509
"\nDownloading %s from:\n%s ..."
498510
% (headless_ie_file_name, headless_ie_url)
499511
)
500-
remote_file = requests.get(headless_ie_url)
512+
remote_file = requests_get_with_retry(headless_ie_url)
501513
with open(headless_ie_file_path, "wb") as file:
502514
file.write(remote_file.content)
503515
print("Download Complete!\n")
@@ -572,7 +584,7 @@ def main(override=None):
572584
print("%s[%s] is now ready for use!%s" % (c1, driver_file, cr))
573585

574586
print("\nDownloading %s from:\n%s ..." % (file_name, download_url))
575-
remote_file = requests.get(download_url)
587+
remote_file = requests_get_with_retry(download_url)
576588
with open(file_path, "wb") as file:
577589
file.write(remote_file.content)
578590
print("Download Complete!\n")

seleniumbase/fixtures/base_case.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,6 +2275,7 @@ def drag_and_drop(
22752275
drag_by="css selector",
22762276
drop_by="css selector",
22772277
timeout=None,
2278+
jquery=False,
22782279
):
22792280
"""Drag and drop an element from one selector to another."""
22802281
self.__check_scope()
@@ -2292,22 +2293,28 @@ def drag_and_drop(
22922293
drag_selector, by=drag_by, timeout=timeout
22932294
)
22942295
self.__demo_mode_highlight_if_active(drag_selector, drag_by)
2295-
self.wait_for_element_visible(
2296+
drop_element = self.wait_for_element_visible(
22962297
drop_selector, by=drop_by, timeout=timeout
22972298
)
22982299
self.__demo_mode_highlight_if_active(drop_selector, drop_by)
22992300
self.scroll_to(drag_selector, by=drag_by)
23002301
drag_selector = self.convert_to_css_selector(drag_selector, drag_by)
23012302
drop_selector = self.convert_to_css_selector(drop_selector, drop_by)
2302-
drag_and_drop_script = js_utils.get_drag_and_drop_script()
2303-
self.safe_execute_script(
2304-
drag_and_drop_script
2305-
+ (
2306-
"$('%s').simulateDragDrop("
2307-
"{dropTarget: "
2308-
"'%s'});" % (drag_selector, drop_selector)
2303+
if not jquery:
2304+
drag_and_drop_script = js_utils.get_js_drag_and_drop_script()
2305+
self.execute_script(
2306+
drag_and_drop_script, drag_element, drop_element, 0, 0, 1, None
2307+
)
2308+
else:
2309+
drag_and_drop_script = js_utils.get_drag_and_drop_script()
2310+
self.safe_execute_script(
2311+
drag_and_drop_script
2312+
+ (
2313+
"$('%s').simulateDragDrop("
2314+
"{dropTarget: "
2315+
"'%s'});" % (drag_selector, drop_selector)
2316+
)
23092317
)
2310-
)
23112318
if self.demo_mode:
23122319
self.__demo_mode_pause_if_active()
23132320
elif self.slow_mode:
@@ -2332,7 +2339,7 @@ def drag_and_drop_with_offset(
23322339
script = js_utils.get_drag_and_drop_with_offset_script(
23332340
css_selector, x, y
23342341
)
2335-
self.safe_execute_script(script)
2342+
self.execute_script(script)
23362343
if self.demo_mode:
23372344
self.__demo_mode_pause_if_active()
23382345
elif self.slow_mode:

seleniumbase/fixtures/js_utils.py

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,10 @@ def raise_unable_to_load_jquery_exception(driver):
151151

152152

153153
def activate_jquery(driver):
154-
"""If "jQuery is not defined", use this method to activate it for use.
155-
This happens because jQuery is not always defined on web sites."""
154+
"""
155+
If "jQuery is not defined" on a website, use this method to activate it.
156+
This method is needed because jQuery is not always defined on web sites.
157+
"""
156158
try:
157159
# Let's first find out if jQuery is already defined.
158160
driver.execute_script("jQuery('html');")
@@ -163,20 +165,15 @@ def activate_jquery(driver):
163165
pass
164166
jquery_js = constants.JQuery.MIN_JS
165167
add_js_link(driver, jquery_js)
166-
for x in range(25):
168+
for x in range(27):
167169
# jQuery needs a small amount of time to activate.
168170
try:
169171
driver.execute_script("jQuery('html');")
170172
return
171173
except Exception:
174+
if x == 15:
175+
add_js_link(driver, jquery_js)
172176
time.sleep(0.1)
173-
try:
174-
add_js_link(driver, jquery_js)
175-
time.sleep(0.5)
176-
driver.execute_script("jQuery('head');")
177-
return
178-
except Exception:
179-
pass
180177
# Since jQuery still isn't activating, give up and raise an exception
181178
raise_unable_to_load_jquery_exception(driver)
182179

@@ -1021,6 +1018,8 @@ def slow_scroll_to_element(driver, element, browser):
10211018

10221019

10231020
def get_drag_and_drop_script():
1021+
# This script uses jQuery to perform a Drag-and-Drop action.
1022+
# (Requires the Drag-selector and the Drop-selector to work)
10241023
script = r"""(function( $ ) {
10251024
$.fn.simulateDragDrop = function(options) {
10261025
return this.each(function() {
@@ -1078,7 +1077,57 @@ def get_drag_and_drop_script():
10781077
return script
10791078

10801079

1080+
def get_js_drag_and_drop_script():
1081+
# HTML5 Drag-and-Drop script (Requires extra parameters to work)
1082+
# param1 (WebElement): Source element to drag
1083+
# param2 (WebElement): Target element for the drop (Optional)
1084+
# param3 (int): Optional - Drop offset x relative to the target
1085+
# param4 (int): Optional - Drop offset y relative to the target
1086+
# param4 (int): Optional - Delay in milliseconds (default = 1ms)
1087+
# param5 (string): Optional - Key pressed (ALT or CTRL or SHIFT)
1088+
script = """var t=arguments,e=t[0],n=t[1],i=t[2]||0,o=t[3]||0,r=t[4]||1,
1089+
a=t[5]||'',s='alt'===a||'\ue00a'===a,l='ctrl'===a||'\ue009'===a,
1090+
c='shift'===a||'\ue008'===a,u=e.ownerDocument,
1091+
f=e.getBoundingClientRect(),g=n?n.getBoundingClientRect():f,
1092+
p=f.left+f.width/2,d=f.top+f.height/2,h=g.left+(i||g.width/2),
1093+
m=g.top+(o||g.height/2),v=u.elementFromPoint(p,d),
1094+
y=u.elementFromPoint(h,m);if(!v||!y){
1095+
var E=new Error('source or target element is not interactable');
1096+
throw E.code=15,E}var _={constructor:DataTransfer,effectAllowed:null,
1097+
dropEffect:null,types:[],files:Object.setPrototypeOf([],null),
1098+
_items:Object.setPrototypeOf([],{add:function(t,e){
1099+
this[this.length]={_data:''+t,kind:'string',
1100+
type:e,getAsFile:function(){},getAsString:function(t){t(this._data)}},
1101+
_.types.push(e)},remove:function(t){
1102+
Array.prototype.splice.call(this,65535&t,1),_.types.splice(65535&t,1)},
1103+
clear:function(t,e){this.length=0,_.types.length=0}}),
1104+
setData:function(t,e){this.clearData(t),this._items.add(e,t)},
1105+
getData:function(t){for(var e=this._items.length;
1106+
e--&&this._items[e].type!==t;);return e>=0?this._items[e]._data:null},
1107+
clearData:function(t){for(var e=this._items.length;
1108+
e--&&this._items[e].type!==t;);this._items.remove(e)},
1109+
setDragImage:function(t){}};function w(t,e,n,i){
1110+
for(var o=0;o<e.length;++o){var r=u.createEvent('MouseEvent');
1111+
r.initMouseEvent(e[o],!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),
1112+
t.dispatchEvent(r)}i&&setTimeout(i,n)}function D(t,e,n,i){
1113+
var o=u.createEvent('DragEvent');o.initMouseEvent(
1114+
e,!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),Object.setPrototypeOf(
1115+
o,null),o.dataTransfer=_,Object.setPrototypeOf(o,DragEvent.prototype),
1116+
t.dispatchEvent(o),i&&setTimeout(i,n)}
1117+
'items'in DataTransfer.prototype&&(_.items=_._items),
1118+
w(v,['pointerdown','mousedown'],1,function(){
1119+
for(var t=v;t&&!t.draggable;)t=t.parentElement;if(t&&t.contains(v)){
1120+
var e=y.getBoundingClientRect();D(v,'dragstart',r,function(){
1121+
var t=y.getBoundingClientRect();p=t.left+h-e.left,d=t.top+m-e.top,D(
1122+
y,'dragenter',1,function(){D(y,'dragover',r,
1123+
function(){D(u.elementFromPoint(p,d),'drop',1,function(){D(v,'dragend',
1124+
1,function(){w(u.elementFromPoint(p,d),
1125+
['mouseup','pointerup'])})})})})})}})"""
1126+
return script
1127+
1128+
10811129
def get_drag_and_drop_with_offset_script(selector, x, y):
1130+
# This script uses pure JS (No jQuery)
10821131
script_a = """
10831132
var source = document.querySelector("%s");
10841133
var offsetX = %f;

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@
257257
'typing-extensions==3.10.0.2;python_version<"3.6"', # <3.9 for "rich"
258258
'typing-extensions==4.1.1;python_version>="3.6" and python_version<"3.7"', # noqa: E501
259259
'typing-extensions==4.2.0;python_version>="3.7" and python_version<"3.9"', # noqa: E501
260-
'rich==12.4.4;python_version>="3.6" and python_version<"4.0"',
260+
'rich==12.5.1;python_version>="3.6" and python_version<"4.0"',
261261
'tornado==5.1.1;python_version<"3.5"',
262262
'tornado==6.1;python_version>="3.5" and python_version<"3.7"',
263263
'tornado==6.2;python_version>="3.7"',

0 commit comments

Comments
 (0)