Skip to content

Commit d05d1a7

Browse files
authored
Merge pull request #664 from seleniumbase/improve-seleniumbase-driver-install
Improve the "seleniumbase install DRIVER" command
2 parents eb56344 + 39fc0c1 commit d05d1a7

File tree

6 files changed

+167
-27
lines changed

6 files changed

+167
-27
lines changed

examples/decryption_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ def test_rate_limited_printing(self):
1414
self.update_text("#user-name", "standard_user")
1515

1616
encrypted_password = "$^*ENCRYPT=S3BDTAdCWzMmKEY8Gjg=?&#$"
17-
print("Encrypted Password = %s" % encrypted_password)
17+
print("\nEncrypted Password = %s" % encrypted_password)
1818
password = encryption.decrypt(encrypted_password)
19-
print("Password = %s" % password)
19+
print("Decrypted Password = %s" % password)
2020
self.update_text("#password", password)
2121

2222
self.click('input[type="submit"]')

examples/test_chromedriver.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""
2+
This test is only for Chrome!
3+
(Verify that your chromedriver is compatible with your version of Chrome.)
4+
"""
5+
import colorama
6+
from seleniumbase import BaseCase
7+
8+
9+
class ChromeTestClass(BaseCase):
10+
11+
def test_chromedriver_matches_chrome(self):
12+
if self.browser != "chrome":
13+
print("\n This test is only for Chrome!")
14+
print(" (Run with: '--browser=chrome')")
15+
self.skip("This test is only for Chrome!")
16+
driver_capabilities = self.driver.__dict__["capabilities"]
17+
if "version" in driver_capabilities:
18+
chrome_version = driver_capabilities["version"]
19+
else:
20+
chrome_version = driver_capabilities["browserVersion"]
21+
major_chrome_version = chrome_version.split('.')[0]
22+
chrome_dict = self.driver.__dict__["capabilities"]["chrome"]
23+
chromedriver_version = chrome_dict["chromedriverVersion"]
24+
chromedriver_version = chromedriver_version.split(' ')[0]
25+
major_chromedriver_version = chromedriver_version.split('.')[0]
26+
c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
27+
c2 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
28+
c3 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
29+
c4 = colorama.Fore.RED + colorama.Back.LIGHTYELLOW_EX
30+
c5 = colorama.Fore.RED + colorama.Back.LIGHTGREEN_EX
31+
cr = colorama.Style.RESET_ALL
32+
pr_chromedriver_version = c3 + chromedriver_version + cr
33+
pr_chrome_version = c2 + chrome_version + cr
34+
message = (
35+
"\n"
36+
"* Your version of chromedriver is: %s\n"
37+
"*\n* And your version of Chrome is: %s"
38+
"" % (pr_chromedriver_version, pr_chrome_version))
39+
print(message)
40+
if major_chromedriver_version < major_chrome_version:
41+
install_sb = (
42+
"seleniumbase install chromedriver %s" % major_chrome_version)
43+
pr_install_sb = c1 + install_sb + cr
44+
up_msg = "You may want to upgrade your version of chromedriver:"
45+
up_msg = c4 + up_msg + cr
46+
message = ("*\n* %s\n*\n* >>> %s" % (up_msg, pr_install_sb))
47+
print(message)
48+
elif major_chromedriver_version > major_chrome_version:
49+
up_msg = "You may want to upgrade your version of Chrome:"
50+
up_msg = c5 + up_msg + cr
51+
up_url = c1 + "chrome://settings/help" + cr
52+
message = ("*\n* %s\n*\n* See: %s" % (up_msg, up_url))
53+
print(message)
54+
else:
55+
up_msg = (
56+
"Success! Your chromedriver is compatible with your Chrome!")
57+
up_msg = c1 + up_msg + cr
58+
message = ("*\n* %s\n" % up_msg)
59+
print(message)

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ requests==2.24.0
1616
selenium==3.141.0
1717
msedge-selenium-tools==3.141.2
1818
pluggy==0.13.1
19-
attrs>=19.3.0
19+
attrs>=20.1.0
2020
py==1.8.1;python_version<"3.5"
2121
py==1.9.0;python_version>="3.5"
2222
pytest==4.6.11;python_version<"3.5"
@@ -52,7 +52,7 @@ brython>=3.8.9
5252
pyotp==2.4.0
5353
boto==2.49.0
5454
cffi==1.14.2
55-
rich==5.2.0;python_version>="3.6" and python_version<"4.0"
55+
rich==5.2.1;python_version>="3.6" and python_version<"4.0"
5656
flake8==3.7.9;python_version<"3.5"
5757
flake8==3.8.3;python_version>="3.5"
5858
pyflakes==2.1.1;python_version<"3.5"

seleniumbase/console_scripts/sb_install.py

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
seleniumbase install chromedriver
1414
seleniumbase install geckodriver
1515
seleniumbase install edgedriver
16+
seleniumbase install edgedriver 84.0.522.61
17+
seleniumbase install chromedriver 84
1618
seleniumbase install chromedriver 84.0.4147.30
1719
seleniumbase install chromedriver latest
1820
seleniumbase install chromedriver -p
1921
seleniumbase install chromedriver latest -p
20-
seleniumbase install edgedriver 84.0.522.61
2122
Output:
2223
Installs the chosen webdriver to seleniumbase/drivers/
2324
(chromedriver is required for Chrome automation)
@@ -27,6 +28,7 @@
2728
(operadriver is required for Opera Browser automation)
2829
"""
2930

31+
import colorama
3032
import os
3133
import platform
3234
import requests
@@ -108,18 +110,28 @@ def main(override=None):
108110
platform_code = None
109111
inner_folder = None
110112
copy_to_path = False
113+
latest_version = ""
111114
use_version = ""
112115
new_file = ""
113116
f_name = ""
117+
c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
118+
c2 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
119+
c3 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
120+
cr = colorama.Style.RESET_ALL
114121

115122
if name == "chromedriver":
123+
last = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"
116124
use_version = DEFAULT_CHROMEDRIVER_VERSION
117125
get_latest = False
126+
get_v_latest = False
118127
if num_args == 4 or num_args == 5:
119128
if "-p" not in sys.argv[3].lower():
120129
use_version = sys.argv[3]
121-
if use_version.lower() == "latest":
130+
uv_low = use_version.lower()
131+
if uv_low == "latest":
122132
get_latest = True
133+
elif len(uv_low) < 4 and uv_low.isdigit() and int(uv_low) > 69:
134+
get_v_latest = True
123135
else:
124136
copy_to_path = True
125137
if num_args == 5:
@@ -138,20 +150,48 @@ def main(override=None):
138150
"to download!")
139151
found_chromedriver = False
140152
if get_latest:
141-
last = "http://chromedriver.storage.googleapis.com/LATEST_RELEASE"
142153
url_request = requests.get(last)
143154
if url_request.ok:
144155
found_chromedriver = True
145156
use_version = url_request.text
146-
download_url = ("http://chromedriver.storage.googleapis.com/"
157+
elif get_v_latest:
158+
url_req = requests.get(last)
159+
if url_req.ok:
160+
latest_version = url_req.text
161+
last = last + "_" + use_version
162+
url_request = requests.get(last)
163+
if url_request.ok:
164+
found_chromedriver = True
165+
use_version = url_request.text
166+
if use_version == latest_version:
167+
get_latest = True
168+
download_url = ("https://chromedriver.storage.googleapis.com/"
147169
"%s/%s" % (use_version, file_name))
148170
url_request = None
149171
if not found_chromedriver:
172+
url_req = requests.get(last)
173+
if url_req.ok:
174+
latest_version = url_req.text
175+
if use_version == latest_version:
176+
get_latest = True
150177
url_request = requests.get(download_url)
151178
if found_chromedriver or url_request.ok:
152-
print("\n* chromedriver version for download = %s" % use_version)
179+
p_version = use_version
180+
p_version = c3 + use_version + cr
181+
if get_latest:
182+
p_version = p_version + " (Latest)"
183+
else:
184+
p_version = p_version + " (NOT Latest)"
185+
msg = c2 + "chromedriver version for download" + cr
186+
print("\n*** %s = %s" % (msg, p_version))
153187
else:
154188
raise Exception("Could not find chromedriver to download!\n")
189+
if not get_latest:
190+
to_upgrade = " " + c3 + "To upgrade" + cr
191+
run_this = c3 + "run this" + cr
192+
install_sb = c1 + "seleniumbase install chromedriver latest" + cr
193+
print("\n#%s to the latest version of chromedriver," % to_upgrade)
194+
print('# %s: >>> %s' % (run_this, install_sb))
155195
elif name == "geckodriver" or name == "firefoxdriver":
156196
use_version = DEFAULT_GECKODRIVER_VERSION
157197
if "win32" in sys_plat or "win64" in sys_plat or "x64" in sys_plat:
@@ -196,7 +236,9 @@ def main(override=None):
196236
if not found_geckodriver:
197237
url_request = requests.get(download_url)
198238
if found_geckodriver or url_request.ok:
199-
print("\n* geckodriver version for download = %s" % use_version)
239+
msg = c2 + "geckodriver version for download" + cr
240+
p_version = c3 + use_version + cr
241+
print("\n*** %s = %s" % (msg, p_version))
200242
else:
201243
raise Exception("\nCould not find the specified geckodriver "
202244
"version to download!\n")
@@ -226,6 +268,9 @@ def main(override=None):
226268
"only for Windows or Mac operating systems!")
227269
download_url = ("https://msedgedriver.azureedge.net/"
228270
"%s/%s" % (use_version, file_name))
271+
msg = c2 + "edgedriver version for download" + cr
272+
p_version = c3 + use_version + cr
273+
print("\n*** %s = %s" % (msg, p_version))
229274
elif name == "iedriver":
230275
major_version = "3.14"
231276
full_version = "3.14.0"
@@ -237,7 +282,7 @@ def main(override=None):
237282
else:
238283
raise Exception("Sorry! IEDriver is only for "
239284
"Windows-based operating systems!")
240-
download_url = ("http://selenium-release.storage.googleapis.com/"
285+
download_url = ("https://selenium-release.storage.googleapis.com/"
241286
"%s/%s" % (major_version, file_name))
242287
elif name == "operadriver" or name == "operachromiumdriver":
243288
name = "operadriver"
@@ -290,6 +335,9 @@ def main(override=None):
290335
download_url = ("https://github.com/operasoftware/operachromiumdriver/"
291336
"releases/download/"
292337
"%s/%s" % (use_version, file_name))
338+
msg = c2 + "operadriver version for download" + cr
339+
p_version = c3 + use_version + cr
340+
print("\n*** %s = %s" % (msg, p_version))
293341
else:
294342
invalid_run_command()
295343

@@ -326,15 +374,16 @@ def main(override=None):
326374
print('Unzip Complete!\n')
327375
for f_name in contents:
328376
new_file = downloads_folder + '/' + str(f_name)
329-
print("The file [%s] was saved to:\n%s\n" % (f_name, new_file))
377+
pr_file = c3 + new_file + cr
378+
print("The file [%s] was saved to:\n%s\n" % (f_name, pr_file))
330379
print("Making [%s %s] executable ..." % (f_name, use_version))
331380
make_executable(new_file)
332-
print("[%s] is now ready for use!" % f_name)
381+
print("%s[%s] is now ready for use!%s" % (c1, f_name, cr))
333382
if copy_to_path and os.path.exists(LOCAL_PATH):
334383
path_file = LOCAL_PATH + f_name
335384
shutil.copyfile(new_file, path_file)
336385
make_executable(path_file)
337-
print("Also copied to: %s" % path_file)
386+
print("Also copied to: %s%s%s" % (c3, path_file, cr))
338387
print("")
339388
elif name == "edgedriver" or name == "msedgedriver":
340389
if "darwin" in sys_plat or "linux" in sys_plat:
@@ -364,7 +413,7 @@ def main(override=None):
364413
if os.path.exists(new_file):
365414
os.remove(new_file)
366415
if not driver_file or not driver_path:
367-
raise Exception("Operadriver missing from Zip file!")
416+
raise Exception("msedgedriver missing from Zip file!")
368417
print('Extracting %s from %s ...' % (contents, file_name))
369418
zip_ref.extractall(downloads_folder)
370419
zip_ref.close()
@@ -382,7 +431,7 @@ def main(override=None):
382431
driver_file, driver_path))
383432
print("Making [%s %s] executable ..." % (driver_file, use_version))
384433
make_executable(driver_path)
385-
print("[%s] is now ready for use!" % driver_file)
434+
print("%s[%s] is now ready for use!%s" % (c1, driver_file, cr))
386435
print("")
387436
elif name == "operadriver":
388437
if len(contents) > 3:
@@ -409,16 +458,17 @@ def main(override=None):
409458
inner_driver = downloads_folder + '/' + inner_folder + driver_file
410459
inner_sha = downloads_folder + '/' + inner_folder + "sha512_sum"
411460
shutil.copyfile(inner_driver, driver_path)
461+
pr_driver_path = c3 + driver_path + cr
412462
print("The file [%s] was saved to:\n%s\n" % (
413-
driver_file, driver_path))
463+
driver_file, pr_driver_path))
414464
print("Making [%s %s] executable ..." % (driver_file, use_version))
415465
make_executable(driver_path)
416-
print("[%s] is now ready for use!" % driver_file)
466+
print("%s[%s] is now ready for use!%s" % (c1, driver_file, cr))
417467
if copy_to_path and os.path.exists(LOCAL_PATH):
418468
path_file = LOCAL_PATH + driver_file
419469
shutil.copyfile(driver_path, path_file)
420470
make_executable(path_file)
421-
print("Also copied to: %s" % path_file)
471+
print("Also copied to: %s%s%s" % (c3, path_file, cr))
422472
# Clean up extra files
423473
if os.path.exists(inner_driver):
424474
os.remove(inner_driver)
@@ -450,15 +500,16 @@ def main(override=None):
450500
print('Unzip Complete!\n')
451501
for f_name in contents:
452502
new_file = downloads_folder + '/' + str(f_name)
453-
print("The file [%s] was saved to:\n%s\n" % (f_name, new_file))
503+
pr_file = c3 + new_file + cr
504+
print("The file [%s] was saved to:\n%s\n" % (f_name, pr_file))
454505
print("Making [%s %s] executable ..." % (f_name, use_version))
455506
make_executable(new_file)
456-
print("[%s] is now ready for use!" % f_name)
507+
print("%s[%s] is now ready for use!%s" % (c1, f_name, cr))
457508
if copy_to_path and os.path.exists(LOCAL_PATH):
458509
path_file = LOCAL_PATH + f_name
459510
shutil.copyfile(new_file, path_file)
460511
make_executable(path_file)
461-
print("Also copied to: %s" % path_file)
512+
print("Also copied to: %s%s%s" % (c3, path_file, cr))
462513
print("")
463514
elif len(contents) == 0:
464515
raise Exception("Tar file %s is empty!" % tar_file_path)
@@ -469,7 +520,7 @@ def main(override=None):
469520
if "Driver" in file_name or "driver" in file_name:
470521
print("Making [%s] executable ..." % file_name)
471522
make_executable(file_path)
472-
print("[%s] is now ready for use!" % file_name)
523+
print("%s[%s] is now ready for use!%s" % (c1, file_name, cr))
473524
print("Location of [%s]:\n%s\n" % (file_name, file_path))
474525

475526

seleniumbase/fixtures/base_case.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,37 @@ def hover_on_element(self, selector, by=By.CSS_SELECTOR):
12361236
self.__demo_mode_highlight_if_active(selector, by)
12371237
self.scroll_to(selector, by=by)
12381238
time.sleep(0.05) # Settle down from scrolling before hovering
1239-
return page_actions.hover_on_element(self.driver, selector)
1239+
if self.browser != "chrome":
1240+
return page_actions.hover_on_element(self.driver, selector)
1241+
# Using Chrome
1242+
# (Pure hover actions won't work on early chromedriver versions)
1243+
try:
1244+
return page_actions.hover_on_element(self.driver, selector)
1245+
except WebDriverException as e:
1246+
driver_capabilities = self.driver.__dict__["capabilities"]
1247+
if "version" in driver_capabilities:
1248+
chrome_version = driver_capabilities["version"]
1249+
else:
1250+
chrome_version = driver_capabilities["browserVersion"]
1251+
major_chrome_version = chrome_version.split('.')[0]
1252+
chrome_dict = self.driver.__dict__["capabilities"]["chrome"]
1253+
chromedriver_version = chrome_dict["chromedriverVersion"]
1254+
chromedriver_version = chromedriver_version.split(' ')[0]
1255+
major_chromedriver_version = chromedriver_version.split('.')[0]
1256+
install_sb = (
1257+
"seleniumbase install chromedriver %s" % major_chrome_version)
1258+
if major_chromedriver_version < major_chrome_version:
1259+
# Upgrading the driver is required for performing hover actions
1260+
message = (
1261+
"\n"
1262+
"You need a newer chromedriver to perform hover actions!\n"
1263+
"Your version of chromedriver is: %s\n"
1264+
"And your version of Chrome is: %s\n"
1265+
"You can fix this issue by running:\n>>> %s\n"
1266+
"" % (chromedriver_version, chrome_version, install_sb))
1267+
raise Exception(message)
1268+
else:
1269+
raise Exception(e)
12401270

12411271
def hover_and_click(self, hover_selector, click_selector,
12421272
hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR,

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.47.0',
57+
version='1.47.1',
5858
description='Web Automation and Test Framework - https://seleniumbase.io',
5959
long_description=long_description,
6060
long_description_content_type='text/markdown',
@@ -108,7 +108,7 @@
108108
'selenium==3.141.0',
109109
'msedge-selenium-tools==3.141.2',
110110
'pluggy==0.13.1',
111-
'attrs>=19.3.0',
111+
'attrs>=20.1.0',
112112
'py==1.8.1;python_version<"3.5"',
113113
'py==1.9.0;python_version>="3.5"',
114114
'pytest==4.6.11;python_version<"3.5"',
@@ -144,7 +144,7 @@
144144
'pyotp==2.4.0',
145145
'boto==2.49.0',
146146
'cffi==1.14.2',
147-
'rich==5.2.0;python_version>="3.6" and python_version<"4.0"',
147+
'rich==5.2.1;python_version>="3.6" and python_version<"4.0"',
148148
'flake8==3.7.9;python_version<"3.5"',
149149
'flake8==3.8.3;python_version>="3.5"',
150150
'pyflakes==2.1.1;python_version<"3.5"',

0 commit comments

Comments
 (0)