Skip to content

Commit 7c2acf5

Browse files
committed
Add the ability to launch IE tests in headless mode
1 parent 3e35b4b commit 7c2acf5

File tree

2 files changed

+154
-4
lines changed

2 files changed

+154
-4
lines changed

seleniumbase/console_scripts/sb_install.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ def main(override=None):
9292
sys.argv = ["seleniumbase", "install", "edgedriver"]
9393
elif override == "geckodriver":
9494
sys.argv = ["seleniumbase", "install", "geckodriver"]
95+
elif override == "iedriver":
96+
sys.argv = ["seleniumbase", "install", "iedriver"]
9597

9698
num_args = len(sys.argv)
9799
if (
@@ -108,6 +110,9 @@ def main(override=None):
108110

109111
file_name = None
110112
download_url = None
113+
headless_ie_url = None
114+
headless_ie_exists = False
115+
headless_ie_file_name = None
111116
downloads_folder = DRIVER_DIR
112117
sys_plat = sys.platform
113118
expected_contents = None
@@ -336,6 +341,19 @@ def main(override=None):
336341
"https://selenium-release.storage.googleapis.com/"
337342
"%s/%s" % (major_version, file_name)
338343
)
344+
headless_ie_version = "v1.4"
345+
headless_ie_file_name = "headless-selenium-for-win-v1-4.zip"
346+
headless_ie_url = (
347+
"https://github.com/kybu/headless-selenium-for-win/"
348+
"releases/download/"
349+
"%s/%s" % (headless_ie_version, headless_ie_file_name)
350+
)
351+
url_request = requests.get(headless_ie_url)
352+
if url_request.ok:
353+
headless_ie_exists = True
354+
msg = c2 + "HeadlessIEDriver version for download" + cr
355+
p_version = c3 + headless_ie_version + cr
356+
print("\n*** %s = %s" % (msg, p_version))
339357
elif name == "operadriver" or name == "operachromiumdriver":
340358
name = "operadriver"
341359
use_version = DEFAULT_OPERADRIVER_VERSION
@@ -411,6 +429,86 @@ def main(override=None):
411429
if not os.path.exists(downloads_folder):
412430
os.mkdir(downloads_folder)
413431

432+
if headless_ie_exists:
433+
headless_ie_file_path = downloads_folder + "/" + headless_ie_file_name
434+
print(
435+
"\nDownloading %s from:\n%s ..."
436+
% (headless_ie_file_name, headless_ie_url)
437+
)
438+
remote_file = requests.get(headless_ie_url)
439+
with open(headless_ie_file_path, "wb") as file:
440+
file.write(remote_file.content)
441+
print("Download Complete!\n")
442+
zip_file_path = headless_ie_file_path
443+
zip_ref = zipfile.ZipFile(zip_file_path, "r")
444+
contents = zip_ref.namelist()
445+
h_ie_fn = headless_ie_file_name.split(".zip")[0]
446+
expected_contents = [
447+
"%s/" % h_ie_fn,
448+
"%s/ruby_example/" % h_ie_fn,
449+
"%s/ruby_example/Gemfile" % h_ie_fn,
450+
"%s/ruby_example/Gemfile.lock" % h_ie_fn,
451+
"%s/ruby_example/ruby_example.rb" % h_ie_fn,
452+
"%s/desktop_utils.exe" % h_ie_fn,
453+
"%s/headless_ie_selenium.exe" % h_ie_fn,
454+
"%s/README.md" % h_ie_fn,
455+
]
456+
if len(contents) > 8:
457+
raise Exception("Unexpected content in HeadlessIEDriver Zip file!")
458+
for content in contents:
459+
if content not in expected_contents:
460+
raise Exception(
461+
"Expected file [%s] missing from [%s]"
462+
% (content, expected_contents)
463+
)
464+
# Zip file is valid. Proceed.
465+
driver_path = None
466+
driver_file = None
467+
filename = None
468+
for f_name in contents:
469+
# Remove existing version if exists
470+
str_name = str(f_name)
471+
new_file = downloads_folder + "/" + str_name
472+
if str_name == "%s/headless_ie_selenium.exe" % h_ie_fn:
473+
driver_file = str_name
474+
driver_path = new_file
475+
filename = "headless_ie_selenium.exe"
476+
if os.path.exists(new_file):
477+
os.remove(new_file)
478+
if not driver_file or not driver_path or not filename:
479+
raise Exception("headless_ie_selenium.exe missing from Zip file!")
480+
print("Extracting %s from %s ..." % (filename, headless_ie_file_name))
481+
zip_ref.extractall(downloads_folder)
482+
zip_ref.close()
483+
os.remove(zip_file_path)
484+
shutil.copyfile(driver_path, "%s/%s" % (downloads_folder, filename))
485+
print("Unzip Complete!\n")
486+
to_remove = [
487+
"%s/%s/ruby_example/Gemfile" % (downloads_folder, h_ie_fn),
488+
"%s/%s/ruby_example/Gemfile.lock" % (downloads_folder, h_ie_fn),
489+
"%s/%s/ruby_example/ruby_example.rb" % (downloads_folder, h_ie_fn),
490+
"%s/%s/desktop_utils.exe" % (downloads_folder, h_ie_fn),
491+
"%s/%s/headless_ie_selenium.exe" % (downloads_folder, h_ie_fn),
492+
"%s/%s/README.md" % (downloads_folder, h_ie_fn),
493+
]
494+
for file_to_remove in to_remove:
495+
if os.path.exists(file_to_remove):
496+
os.remove(file_to_remove)
497+
if os.path.exists("%s/%s/ruby_example/" % (downloads_folder, h_ie_fn)):
498+
# Only works if the directory is empty
499+
os.rmdir("%s/%s/ruby_example/" % (downloads_folder, h_ie_fn))
500+
if os.path.exists("%s/%s/" % (downloads_folder, h_ie_fn)):
501+
# Only works if the directory is empty
502+
os.rmdir("%s/%s/" % (downloads_folder, h_ie_fn))
503+
driver_path = "%s/%s" % (downloads_folder, filename)
504+
print(
505+
"The file [%s] was saved to:\n%s%s%s\n"
506+
% (filename, c3, driver_path, cr)
507+
)
508+
print("Making [%s %s] executable ..." % (driver_file, use_version))
509+
make_executable(driver_path)
510+
print("%s[%s] is now ready for use!%s" % (c1, driver_file, cr))
511+
414512
print("\nDownloading %s from:\n%s ..." % (file_name, download_url))
415513
remote_file = requests.get(download_url)
416514
with open(file_path, "wb") as file:

seleniumbase/core/browser_launcher.py

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
LOCAL_GECKODRIVER = None
3838
LOCAL_EDGEDRIVER = None
3939
LOCAL_IEDRIVER = None
40+
LOCAL_HEADLESS_IEDRIVER = None
4041
LOCAL_OPERADRIVER = None
4142
if "darwin" in PLATFORM or "linux" in PLATFORM:
4243
LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver"
@@ -47,6 +48,7 @@
4748
IS_WINDOWS = True
4849
LOCAL_EDGEDRIVER = DRIVER_DIR + "/msedgedriver.exe"
4950
LOCAL_IEDRIVER = DRIVER_DIR + "/IEDriverServer.exe"
51+
LOCAL_HEADLESS_IEDRIVER = DRIVER_DIR + "/headless_ie_selenium.exe"
5052
LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver.exe"
5153
LOCAL_GECKODRIVER = DRIVER_DIR + "/geckodriver.exe"
5254
LOCAL_OPERADRIVER = DRIVER_DIR + "/operadriver.exe"
@@ -73,7 +75,9 @@ def make_driver_executable_if_not(driver_path):
7375
def is_chromedriver_on_path():
7476
paths = os.environ["PATH"].split(os.pathsep)
7577
for path in paths:
76-
if os.path.exists(path + "/" + "chromedriver"):
78+
if (not IS_WINDOWS) and os.path.exists(path + "/chromedriver"):
79+
return True
80+
elif IS_WINDOWS and os.path.exists(path + "/chromedriver.exe"):
7781
return True
7882
return False
7983

@@ -85,11 +89,25 @@ def is_edgedriver_on_path():
8589
def is_geckodriver_on_path():
8690
paths = os.environ["PATH"].split(os.pathsep)
8791
for path in paths:
88-
if os.path.exists(path + "/" + "geckodriver"):
92+
if (not IS_WINDOWS) and os.path.exists(path + "/geckodriver"):
93+
return True
94+
elif IS_WINDOWS and os.path.exists(path + "/geckodriver.exe"):
95+
return True
96+
return False
97+
98+
99+
def is_iedriver_on_path():
100+
paths = os.environ["PATH"].split(os.pathsep)
101+
for path in paths:
102+
if os.path.exists(path + "/IEDriverServer.exe"):
89103
return True
90104
return False
91105

92106

107+
def is_headless_iedriver_on_path():
108+
return os.path.exists(LOCAL_HEADLESS_IEDRIVER)
109+
110+
93111
def _add_chrome_proxy_extension(
94112
chrome_options, proxy_string, proxy_user, proxy_pass
95113
):
@@ -1049,9 +1067,43 @@ def get_local_driver(
10491067
make_driver_executable_if_not(LOCAL_IEDRIVER)
10501068
except Exception as e:
10511069
logging.debug(
1052-
"\nWarning: Could not make iedriver executable: %s" % e
1070+
"\nWarning: Could not make IEDriver executable: %s" % e
1071+
)
1072+
elif not is_iedriver_on_path():
1073+
args = " ".join(sys.argv)
1074+
if not ("-n" in sys.argv or " -n=" in args or args == "-c"):
1075+
# (Not multithreaded)
1076+
from seleniumbase.console_scripts import sb_install
1077+
1078+
sys_args = sys.argv # Save a copy of current sys args
1079+
print("\nWarning: IEDriver not found. Installing now:")
1080+
sb_install.main(override="iedriver")
1081+
sys.argv = sys_args # Put back the original sys args
1082+
if LOCAL_HEADLESS_IEDRIVER and os.path.exists(LOCAL_HEADLESS_IEDRIVER):
1083+
try:
1084+
make_driver_executable_if_not(LOCAL_HEADLESS_IEDRIVER)
1085+
except Exception as e:
1086+
logging.debug(
1087+
"\nWarning: Could not make HeadlessIEDriver executable: %s"
1088+
% e
10531089
)
1054-
return webdriver.Ie(capabilities=ie_capabilities)
1090+
elif not is_headless_iedriver_on_path():
1091+
args = " ".join(sys.argv)
1092+
if not ("-n" in sys.argv or " -n=" in args or args == "-c"):
1093+
# (Not multithreaded)
1094+
from seleniumbase.console_scripts import sb_install
1095+
1096+
sys_args = sys.argv # Save a copy of current sys args
1097+
print("\nWarning: HeadlessIEDriver not found. Installing now:")
1098+
sb_install.main(override="iedriver")
1099+
sys.argv = sys_args # Put back the original sys args
1100+
if not headless:
1101+
return webdriver.Ie(capabilities=ie_capabilities)
1102+
else:
1103+
return webdriver.Ie(
1104+
executable_path=LOCAL_HEADLESS_IEDRIVER,
1105+
capabilities=ie_capabilities,
1106+
)
10551107
elif browser_name == constants.Browser.EDGE:
10561108
prefs = {
10571109
"download.default_directory": downloads_path,

0 commit comments

Comments
 (0)