@@ -61,6 +61,12 @@ def test_anything(self):
6161from seleniumbase import config as sb_config
6262from seleniumbase.__version__ import __version__
6363from seleniumbase.common import decorators
64+ from seleniumbase.common.exceptions import (
65+ NotUsingChromeException,
66+ NotUsingChromiumException,
67+ OutOfScopeException,
68+ VisualException,
69+ )
6470from seleniumbase.config import settings
6571from seleniumbase.core import download_helper
6672from seleniumbase.core import log_helper
@@ -6427,11 +6433,15 @@ def save_element_as_image_file(
64276433 def download_file(self, file_url, destination_folder=None):
64286434 """Downloads the file from the url to the destination folder.
64296435 If no destination folder is specified, the default one is used.
6430- (The default [Downloads Folder] = "./downloaded_files")"""
6431- if not destination_folder:
6432- destination_folder = constants.Files.DOWNLOADS_FOLDER
6433- if not os.path.exists(destination_folder):
6434- os.makedirs(destination_folder)
6436+ (The default folder for downloads is "./downloaded_files")"""
6437+ download_file_lock = fasteners.InterProcessLock(
6438+ constants.MultiBrowser.DOWNLOAD_FILE_LOCK
6439+ )
6440+ with download_file_lock:
6441+ if not destination_folder:
6442+ destination_folder = constants.Files.DOWNLOADS_FOLDER
6443+ if not os.path.exists(destination_folder):
6444+ os.makedirs(destination_folder)
64356445 page_utils._download_file_to(file_url, destination_folder)
64366446 if self.recorder_mode:
64376447 url = self.get_current_url()
@@ -6489,6 +6499,12 @@ def get_browser_downloads_folder(self):
64896499 and self.headless
64906500 ):
64916501 return os.path.join(os.path.expanduser("~"), "downloads")
6502+ elif (
6503+ self.driver.capabilities["browserName"].lower() == "chrome"
6504+ and int(self.get_chromedriver_version().split(".")[0]) >= 110
6505+ and self.headless
6506+ ):
6507+ return os.path.abspath(".")
64926508 else:
64936509 return download_helper.get_downloads_folder()
64946510 return os.path.join(os.path.expanduser("~"), "downloads")
@@ -7088,17 +7104,27 @@ def __fail_if_not_using_chrome(self, method):
70887104 if browser_name.lower() == "chrome":
70897105 chrome = True
70907106 if not chrome:
7091- from seleniumbase.common.exceptions import NotUsingChromeException
7092-
70937107 message = (
7094- 'Error: "%s" should only be called '
7095- 'by tests running with self. browser == " chrome"! '
7108+ 'Error: "%s" should only be called by tests '
7109+ 'running with "-- browser=chrome" / "-- chrome"! '
70967110 'You should add an "if" statement to your code before calling '
70977111 "this method if using browsers that are Not Chrome! "
70987112 'The browser detected was: "%s".' % (method, browser_name)
70997113 )
71007114 raise NotUsingChromeException(message)
71017115
7116+ def __fail_if_not_using_chromium(self, method):
7117+ browser_name = self.driver.capabilities["browserName"]
7118+ if not self.is_chromium():
7119+ message = (
7120+ 'Error: "%s" should only be called by tests '
7121+ 'running with a Chromium browser! (Chrome or Edge) '
7122+ 'You should add an "if" statement to your code before calling '
7123+ "this method if using browsers that are Not Chromium! "
7124+ 'The browser detected was: "%s".' % (method, browser_name)
7125+ )
7126+ raise NotUsingChromiumException(message)
7127+
71027128 def get_chrome_version(self):
71037129 self.__check_scope()
71047130 self.__fail_if_not_using_chrome("get_chrome_version()")
@@ -7109,6 +7135,11 @@ def get_chrome_version(self):
71097135 chrome_version = driver_capabilities["browserVersion"]
71107136 return chrome_version
71117137
7138+ def get_chromium_version(self):
7139+ self.__check_scope()
7140+ self.__fail_if_not_using_chromium("get_chromium_version()")
7141+ return self.__get_major_browser_version()
7142+
71127143 def get_chromedriver_version(self):
71137144 self.__check_scope()
71147145 self.__fail_if_not_using_chrome("get_chromedriver_version()")
@@ -7117,14 +7148,19 @@ def get_chromedriver_version(self):
71177148 chromedriver_version = chromedriver_version.split(" ")[0]
71187149 return chromedriver_version
71197150
7120- def is_chromedriver_too_old(self):
7121- """Before chromedriver 73, there was no version check, which
7122- means it's possible to run a new Chrome with old drivers."""
7151+ def get_chromium_driver_version(self):
71237152 self.__check_scope()
7124- self.__fail_if_not_using_chrome("is_chromedriver_too_old()")
7125- if int(self.get_chromedriver_version().split(".")[0]) < 73:
7126- return True # chromedriver is too old! Please upgrade!
7127- return False
7153+ self.__fail_if_not_using_chromium("get_chromium_version()")
7154+ driver_version = None
7155+ if "chrome" in self.driver.capabilities:
7156+ chrome_dict = self.driver.capabilities["chrome"]
7157+ driver_version = chrome_dict["chromedriverVersion"]
7158+ driver_version = driver_version.split(" ")[0]
7159+ elif "msedge" in self.driver.capabilities:
7160+ edge_dict = self.driver.capabilities["msedge"]
7161+ driver_version = edge_dict["msedgedriverVersion"]
7162+ driver_version = driver_version.split(" ")[0]
7163+ return driver_version
71287164
71297165 def get_mfa_code(self, totp_key=None):
71307166 """Same as get_totp_code() and get_google_auth_password().
@@ -9303,8 +9339,6 @@ def __assert_eq(self, *args, **kwargs):
93039339 elif line.strip().startswith("*"):
93049340 minified_exception += line + "\n"
93059341 if minified_exception:
9306- from seleniumbase.common.exceptions import VisualException
9307-
93089342 raise VisualException(minified_exception)
93099343
93109344 def _process_visual_baseline_logs(self):
@@ -9684,8 +9718,6 @@ def __check_scope(self):
96849718 if hasattr(self, "browser"): # self.browser stores the type of browser
96859719 return # All good: setUp() already initialized variables in "self"
96869720 else:
9687- from seleniumbase.common.exceptions import OutOfScopeException
9688-
96899721 message = (
96909722 "\n It looks like you are trying to call a SeleniumBase method"
96919723 "\n from outside the scope of your test class's `self` object,"
@@ -12730,9 +12762,18 @@ def __disable_beforeunload_as_needed(self):
1273012762
1273112763 ############
1273212764
12765+ @decorators.deprecated("The Driver Manager prevents old drivers.")
12766+ def is_chromedriver_too_old(self):
12767+ """Before chromedriver 73, there was no version check, which
12768+ means it's possible to run a new Chrome with old drivers."""
12769+ self.__fail_if_not_using_chrome("is_chromedriver_too_old()")
12770+ if int(self.get_chromedriver_version().split(".")[0]) < 73:
12771+ return True # chromedriver is too old! Please upgrade!
12772+ return False
12773+
1273312774 @decorators.deprecated("You should use re.escape() instead.")
1273412775 def jq_format(self, code):
12735- # DEPRECATED - re.escape() already performs the intended action.
12776+ # DEPRECATED - re.escape() already performs this action.
1273612777 return js_utils._jq_format(code)
1273712778
1273812779 ############
0 commit comments