Skip to content

Commit 0eae9a8

Browse files
committed
Add a console script for installing web drivers
1 parent c10345a commit 0eae9a8

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

console_scripts/sb_install.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
"""
2+
Installs the specified web driver.
3+
4+
Usage:
5+
seleniumbase install {chromedriver|geckodriver|edgedriver}
6+
Output:
7+
Installs the specified webdriver.
8+
(chromedriver is required for Chrome automation)
9+
(geckodriver is required for Firefox automation)
10+
(edgedriver is required for MS Edge automation)
11+
"""
12+
13+
import os
14+
import platform
15+
import requests
16+
import sys
17+
import tarfile
18+
import zipfile
19+
import drivers # webdriver storage folder for SeleniumBase
20+
if sys.version_info[0] == 2:
21+
from urllib import urlopen
22+
else:
23+
from urllib.request import urlopen
24+
DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
25+
26+
27+
def invalid_run_command():
28+
exp = (" ** install **\n\n")
29+
exp += " Usage:\n"
30+
exp += " seleniumbase install [DRIVER_NAME]\n"
31+
exp += " (Drivers: chromedriver, geckodriver, edgedriver)\n"
32+
exp += " Example:\n"
33+
exp += " seleniumbase install chromedriver\n"
34+
exp += " Output:\n"
35+
exp += " Installs the specified webdriver.\n"
36+
exp += " (chromedriver is required for Chrome automation)\n"
37+
exp += " (geckodriver is required for Firefox automation)\n"
38+
exp += " (edgedriver is required for MS Edge automation)\n"
39+
print("")
40+
raise Exception('INVALID RUN COMMAND!\n\n%s' % exp)
41+
42+
43+
def make_executable(file_path):
44+
# Set permissions to: "If you can read it, you can execute it."
45+
mode = os.stat(file_path).st_mode
46+
mode |= (mode & 0o444) >> 2 # copy R bits to X
47+
os.chmod(file_path, mode)
48+
49+
50+
def main():
51+
num_args = len(sys.argv)
52+
if sys.argv[0].split('/')[-1] == "seleniumbase" or (
53+
sys.argv[0].split('\\')[-1] == "seleniumbase"):
54+
if num_args < 3 or num_args > 3:
55+
invalid_run_command()
56+
else:
57+
invalid_run_command()
58+
name = sys.argv[num_args-1]
59+
60+
file_name = None
61+
download_url = None
62+
downloads_folder = DRIVER_DIR
63+
64+
if name == "chromedriver":
65+
if "darwin" in sys.platform:
66+
file_name = "chromedriver_mac64.zip"
67+
elif "linux" in sys.platform:
68+
file_name = "chromedriver_linux64.zip"
69+
elif "win32" in sys.platform or "win64" in sys.platform:
70+
file_name = "chromedriver_win32.zip" # Works for win32 and win64
71+
else:
72+
raise Exception("Cannon determine which version of Chromedriver "
73+
"to download!")
74+
75+
latest_version = requests.get(
76+
"http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text
77+
download_url = ("http://chromedriver.storage.googleapis.com/"
78+
"%s/%s" % (latest_version, file_name))
79+
print('\nLocating the latest version of Chromedriver...')
80+
if not requests.get(download_url).ok:
81+
# If there's a problem with the latest Chromedriver, fall back
82+
fallback_version = "2.41"
83+
download_url = ("http://chromedriver.storage.googleapis.com/"
84+
"%s/%s" % (fallback_version, file_name))
85+
print("Found %s" % download_url)
86+
elif name == "geckodriver" or name == "firefoxdriver":
87+
latest_version = "v0.21.0"
88+
if "darwin" in sys.platform:
89+
file_name = "geckodriver-%s-macos.tar.gz" % latest_version
90+
elif "linux" in sys.platform:
91+
arch = platform.architecture()[0]
92+
if "64" in arch:
93+
file_name = "geckodriver-%s-linux64.tar.gz" % latest_version
94+
else:
95+
file_name = "geckodriver-%s-linux32.tar.gz" % latest_version
96+
elif "win32" in sys.platform:
97+
file_name = "geckodriver-%s-win32.zip" % latest_version
98+
elif "win64" in sys.platform:
99+
file_name = "geckodriver-%s-win64.zip" % latest_version
100+
else:
101+
raise Exception("Cannon determine which version of Geckodriver "
102+
"(Firefox Driver) to download!")
103+
104+
download_url = ("http://github.com/mozilla/geckodriver/"
105+
"releases/download/"
106+
"%s/%s" % (latest_version, file_name))
107+
elif name == "edgedriver" or name == "microsoftwebdriver":
108+
if "win32" in sys.platform or "win64" in sys.platform:
109+
version_code = "F/8/A/F8AF50AB-3C3A-4BC4-8773-DC27B32988DD"
110+
file_name = "MicrosoftWebDriver.exe"
111+
download_url = ("https://download.microsoft.com/download/"
112+
"%s/%s" % (version_code, file_name))
113+
else:
114+
raise Exception("Sorry! Microsoft WebDriver / EdgeDriver is "
115+
"only for Windows-based operating systems!")
116+
else:
117+
invalid_run_command()
118+
119+
if file_name is None or download_url is None:
120+
invalid_run_command()
121+
122+
file_path = downloads_folder + '/' + file_name
123+
if not os.path.exists(downloads_folder):
124+
os.mkdir(downloads_folder)
125+
local_file = open(file_path, 'wb')
126+
remote_file = urlopen(download_url)
127+
print('\nDownloading %s from:\n%s ...' % (file_name, download_url))
128+
local_file.write(remote_file.read())
129+
local_file.close()
130+
remote_file.close()
131+
print('Download Complete!\n')
132+
133+
if file_name.endswith(".zip"):
134+
zip_file_path = file_path
135+
zip_ref = zipfile.ZipFile(zip_file_path, 'r')
136+
contents = zip_ref.namelist()
137+
if len(contents) == 1:
138+
for f_name in contents:
139+
# remove existing version if exists
140+
new_file = downloads_folder + '/' + str(f_name)
141+
if "Driver" in new_file or "driver" in new_file:
142+
if os.path.exists(new_file):
143+
os.remove(new_file) # Technically the old file now
144+
print('Extracting %s from %s ...' % (contents, file_name))
145+
zip_ref.extractall(downloads_folder)
146+
zip_ref.close()
147+
os.remove(zip_file_path)
148+
print('Unzip Complete!\n')
149+
for f_name in contents:
150+
new_file = downloads_folder + '/' + str(f_name)
151+
print("%s saved!\n" % new_file)
152+
print("Making %s executable ..." % new_file)
153+
make_executable(new_file)
154+
print("%s is now ready for use!" % new_file)
155+
print("")
156+
elif len(contents) == 0:
157+
raise Exception("Zip file %s is empty!" % zip_file_path)
158+
else:
159+
raise Exception("Expecting only one file in %s!" % zip_file_path)
160+
elif file_name.endswith(".tar.gz"):
161+
tar_file_path = file_path
162+
tar = tarfile.open(file_path)
163+
contents = tar.getnames()
164+
if len(contents) == 1:
165+
for f_name in contents:
166+
# remove existing version if exists
167+
new_file = downloads_folder + '/' + str(f_name)
168+
if "Driver" in new_file or "driver" in new_file:
169+
if os.path.exists(new_file):
170+
os.remove(new_file) # Technically the old file now
171+
print('Extracting %s from %s ...' % (contents, file_name))
172+
tar.extractall(downloads_folder)
173+
tar.close()
174+
os.remove(tar_file_path)
175+
print('Untar Complete!\n')
176+
for f_name in contents:
177+
new_file = downloads_folder + '/' + str(f_name)
178+
print("%s saved!\n" % new_file)
179+
print("Making %s executable ..." % new_file)
180+
make_executable(new_file)
181+
print("%s is now ready for use!" % new_file)
182+
print("")
183+
elif len(contents) == 0:
184+
raise Exception("Tar file %s is empty!" % tar_file_path)
185+
else:
186+
raise Exception("Expecting only one file in %s!" % tar_file_path)
187+
else:
188+
# Not a .zip file or a .tar.gz file. Just a direct download.
189+
if "Driver" in file_name or "driver" in file_name:
190+
print("Making %s executable ..." % file_path)
191+
make_executable(file_path)
192+
print("%s is now ready for use!\n" % file_path)
193+
194+
195+
if __name__ == "__main__":
196+
main()

0 commit comments

Comments
 (0)