def __init__( self, name, version, os_type, url, latest_release_url, ie_release_tag, ): super(IEDriver, self).__init__( name, version, os_type, url, latest_release_url, ) self.os_type = "x64" if os_type == "win64" else "Win32" self._ie_release_tag = ie_release_tag # todo: for 'browser_version' implement installed IE version detection # like chrome or firefox self.browser_version = "" self._os_token = os.getenv("GH_TOKEN", None) self.auth_header = ({ 'Authorization': f'token {self._os_token}' } if self._os_token else None) if self._os_token: log("GH_TOKEN will be used to perform requests", first_line=True)
def install(self): log(f"Current {self.driver.chrome_type} version is {self.driver.browser_version}", first_line=True) driver_path = self._get_driver_path(self.driver) os.chmod(driver_path, 0o755) return driver_path
def get_latest_cached_driver_version(self, driver_name): if not self.is_valid_cache(driver_name): return None metadata = self.read_metadata()[driver_name] log(f"Cache is valid for [{metadata['timestamp']}]", first_line=True) return metadata["latest_version"]
def chrome_version(browser_type=ChromeType.GOOGLE): pattern = r'\d+\.\d+\.\d+' cmd_mapping = { ChromeType.GOOGLE: { OSType.LINUX: 'google-chrome --version || google-chrome-stable --version', OSType.MAC: r'/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version', OSType.WIN: r'reg query "HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon" /v version' }, ChromeType.CHROMIUM: { OSType.LINUX: 'chromium --version || chromium-browser --version', OSType.MAC: r'/Applications/Chromium.app/Contents/MacOS/Chromium --version', OSType.WIN: r'reg query "HKEY_CURRENT_USER\Software\Chromium\BLBeacon" /v version' } } cmd = cmd_mapping[browser_type][os_name()] stdout = os.popen(cmd).read() version = re.search(pattern, stdout) if not version: raise ValueError( f'Could not get version for Chrome with this command: {cmd}') current_version = version.group(0) log(f"Current {browser_type} version {current_version}", first_line=True) return current_version
def get_browser_version_from_os(browser_type=None): """Return installed browser version.""" pattern = r'\d+\.\d+\.\d+' cmd_mapping = { ChromeType.GOOGLE: { OSType.LINUX: linux_browser_apps_to_cmd('google-chrome', 'google-chrome-stable'), OSType.MAC: r'/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version', OSType.WIN: r'reg query "HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon" /v version' }, ChromeType.CHROMIUM: { OSType.LINUX: linux_browser_apps_to_cmd('chromium', 'chromium-browser'), OSType.MAC: r'/Applications/Chromium.app/Contents/MacOS/Chromium --version', OSType.WIN: r'reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome" /v version' }, ChromeType.MSEDGE: { OSType.LINUX: linux_browser_apps_to_cmd('microsoft-edge', 'microsoft-edge-stable', 'microsoft-edge-beta', 'microsoft-edge-dev'), OSType.MAC: r'/Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge --version', OSType.WIN: r'reg query "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\BLBeacon" /v version', } } cmd = cmd_mapping[browser_type][os_name()] version = read_version_from_cmd(cmd, pattern) if not version: log(f'Could not get version for {browser_type} with the any command: {cmd}') current_version = version.group(0) if version else 'UNKNOWN' log(f"Current {browser_type} version is {current_version}") return current_version
def get_latest_release_version(self): # type: () -> str log(f"Get LATEST driver version for {self.browser_version}") resp = requests.get(url=self.latest_release_url, headers=self.auth_header) validate_response(resp) return resp.json()["tag_name"]
def __unpack(self, path, to_directory=None): log(f"Unpack archive {path}") if not to_directory: to_directory = os.path.dirname(path) if path.endswith(".zip"): return extract_zip(path, to_directory) else: file_list = extract_tar_file(path, to_directory) return [x.name for x in file_list]
def __init__(self, root_dir=None, log_level=None, print_first_line=None, cache_valid_range=1): self.driver_cache = DriverCache(root_dir, cache_valid_range) if print_first_line: print("\n") log("====== WebDriver manager ======")
def __init__(self, name, version, os_type, url, latest_release_url, mozila_release_tag): super(GeckoDriver, self).__init__(name, version, os_type, url, latest_release_url) self._mozila_release_tag = mozila_release_tag self._os_token = os.getenv("GH_TOKEN", None) self.auth_header = None if self._os_token: log("GH_TOKEN will be used to perform requests", first_line=True) self.auth_header = {'Authorization': f'token {self._os_token}'}
def __init__(self, root_dir=None, log_level=None, print_first_line=None, cache_valid_range=1): self.driver_cache = DriverCache(root_dir, cache_valid_range) if os.environ.get('WDM_PRINT_FIRST_LINE', str(print_first_line)) == 'True': log("\n", formatter='%(message)s') log("====== WebDriver manager ======")
def __init__(self, root_dir=None, logger: Logger = None, logginglevel=logging.INFO, loggingfile: str = None, cache_valid_range=1): self.driver_cache = DriverCache(root_dir, cache_valid_range) log("====== WebDriver manager ======", logger=logger, filename=loggingfile, level=logginglevel)
def __init__(self, name, version, os_type, url, latest_release_url, opera_release_tag): super(OperaDriver, self).__init__(name, version, os_type, url, latest_release_url) self.opera_release_tag = opera_release_tag self._os_token = os.getenv("GH_TOKEN", None) self.auth_header = None self.browser_version = "" if self._os_token: log("GH_TOKEN will be used to perform requests") self.auth_header = {'Authorization': f'token {self._os_token}'}
def get_latest_release_version(self): self.browser_version = get_browser_version_from_os(self.chrome_type) log(f"Get LATEST {self._name} version for {self.browser_version} {self.chrome_type}" ) latest_release_url = ( f"{self._latest_release_url}_{self.browser_version}" if self.browser_version != "UNKNOWN" else self._latest_release_url) resp = requests.get(url=latest_release_url, verify=self.ssl_verify) validate_response(resp) self._version = resp.text.rstrip() return self._version
def save_file_to_cache(self, file: File, browser_version, driver_name, os_type, driver_version): path = os.path.join(self._drivers_directory, driver_name, os_type, driver_version) archive = save_file(file, path) files = archive.unpack(path) binary = self.__get_binary(files, driver_name) binary_path = os.path.join(path, binary) self.__save_metadata(browser_version, driver_name, os_type, driver_version, binary_path) log(f"Driver has been saved in cache [{path}]") return binary_path
def get_url(self, version): # https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz log(f"Getting latest mozilla release info for {version}") resp = requests.get(url=self.tagged_release_url(version), headers=self.auth_header) validate_response(resp) assets = resp.json()["assets"] name = f"{self.get_name()}-{version}-{self.get_os_type()}" output_dict = [asset for asset in assets if asset['name'].startswith(name)] return output_dict[0]['browser_download_url']
def get_url(self): # https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz log(f"Getting latest mozilla release info for {self.get_version()}") resp = requests.get(url=self.tagged_release_url(self.get_version()), headers=self.auth_header) validate_response(resp) assets = resp.json()["assets"] name = f"{self.get_name()}-{self.get_version()}-{self.get_os_type()}{'-aarch64' if (self.get_os_type() == 'macos' and not platform.processor() == 'i386') else ''}" + "." output_dict = [asset for asset in assets if asset['name'].startswith(name)] return output_dict[0]['browser_download_url']
def get_latest_release_version(self) -> str: self.browser_version = firefox_version() log(f"Get LATEST {self._name} version for {self.browser_version} firefox" ) resp = requests.get( url=self.latest_release_url, headers=self.auth_header, verify=self.ssl_verify, ) validate_response(resp) self._version = resp.json()["tag_name"] return self._version
def __find_file(self, paths, name, version, os_type): log(f"Looking for [{name} {version} {os_type}] driver in cache ") if len(name) == 0 or len(version) == 0: return None if "win" in os_type: name += ".exe" for path in paths: if os.path.isfile(path) and path.endswith(name): log(f"Driver found in cache [{path}]") return path return None
def get_url(self): # type: () -> str # https://github.com/operasoftware/operachromiumdriver/releases/download/v.2.45/operadriver_linux64.zip version = self.get_version() log(f"Getting latest opera release info for {version}") resp = requests.get(url=self.tagged_release_url(version), headers=self.auth_header) validate_response(resp) assets = resp.json()["assets"] name = "{0}_{1}".format(self.get_name(), self.get_os_type()) output_dict = [asset for asset in assets if asset['name'].startswith(name)] return output_dict[0]['browser_download_url']
def get_latest_release_version(self) -> str: log(f"Get LATEST driver version for {self.browser_version}") resp = requests.get( url=self.latest_release_url, headers=self.auth_header, verify=self.ssl_verify, ) validate_response(resp) releases = resp.json() release = next(release for release in releases for asset in release['assets'] if asset['name'].startswith(self.get_name())) self._version = release['tag_name'].replace('selenium-', '') return self._version
def get_url(self): """Like https://github.com/seleniumhq/selenium/releases/download/3.141.59/IEDriverServer_Win32_3.141.59.zip""" log(f"Getting latest ie release info for {self.get_version()}") resp = requests.get( url=self.tagged_release_url(self.get_version()), headers=self.auth_header, verify=self.ssl_verify, ) validate_response(resp) assets = resp.json()["assets"] name = f"{self.get_name()}_{self.os_type}_{self.get_version()}" + "." output_dict = [ asset for asset in assets if asset['name'].startswith(name) ] return output_dict[0]['browser_download_url']
def firefox_version(): pattern = r'(\d+.\d+)' cmd_mapping = { OSType.LINUX: 'firefox --version', OSType.MAC: r'/Applications/Firefox.app/Contents/MacOS/firefox --version', OSType.WIN: r"Powershell (Get-Item (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe').'(Default)').VersionInfo.ProductVersion", } cmd = cmd_mapping[os_name()] version = read_version_from_cmd(cmd, pattern) if not version: log(f'Could not get version for firefox with the any command: {cmd}') current_version = version.group(0) if version else 'UNKNOWN' log(f"Current firefox version is {current_version}") return current_version
def find_driver(self, browser_version, driver_name, os_type, driver_version): metadata = self.get_metadata() key = f"{os_type}_{driver_name}_{driver_version}_for_{browser_version}" if key not in metadata: log(f"There is no [{os_type}] {driver_name} for browser {browser_version} in cache" ) return None driver_info = metadata[key] if not self.__is_valid(driver_info): return None path = driver_info['binary_path'] log(f"Driver [{path}] found in cache") return path
def __init__( self, version="latest", os_type=utils.os_type(), path=None, name="chromedriver", url="http://chromedriver.storage.googleapis.com", latest_release_url="http://chromedriver.storage.googleapis.com/LATEST_RELEASE", chrome_type='chromium', #chrome_type=ChromeType.GOOGLE, log_level=logging.INFO): super().__init__(path, log_level=log_level) self.driver = ChromiumDriver(name=name, version=version, os_type=os_type, url=url, latest_release_url=latest_release_url, chrome_type=chrome_type) # from wdd if os_type in {'linux64', 'linux32', 'mac64', 'mac32'}: # and os.geteuid() == 0: # THIS IS NOT WORKING PROPERLY.... geteuid is not 0 in Docker build base_path = "/usr/local" else: base_path = os.path.expanduser("~") # wdd uses a different download directory # if os_type in {OSType.LINUX, OSType.MAC}: # self.download_root = os.path.join(base_path, "webdriver") # else: # self.download_root = os.path.join(os.environ['HOME'], "webdriver") if os_type in {'linux64', 'linux32', 'mac64', 'mac32'}: self.link_path = os.path.join(base_path, "bin") else: self.link_path = os.path.join(os.environ['HOME'], "bin") # if not os.path.isdir(self.download_root): # os.makedirs(self.download_root) # logger.info("Created download root directory: {0}".format(self.download_root)) if not os.path.isdir(self.link_path): os.makedirs(self.link_path) log("Created symlink directory: {0}".format(self.link_path))
def get_latest_release_version(self) -> str: self.browser_version = get_browser_version_from_os(ChromeType.MSEDGE) log(f"Get LATEST {self._name} version for {self.browser_version} Edge") major_edge_version = self.browser_version.split( ".")[0] if self.browser_version != 'UNKNOWN' else None latest_release_url = ({ OSType.WIN in self.get_os_type(): f'{self._latest_release_url}_{major_edge_version}_WINDOWS', OSType.MAC in self.get_os_type(): f'{self._latest_release_url}_{major_edge_version}_MACOS', OSType.LINUX in self.get_os_type(): f'{self._latest_release_url}_{major_edge_version}_LINUX', }[True] if self.browser_version != "UNKNOWN" else self._latest_release_url.replace( 'LATEST_RELEASE', 'LATEST_STABLE')) resp = requests.get(latest_release_url, verify=self.ssl_verify) validate_response(resp) self._version = resp.text.rstrip() return self._version
def install(self): # chrome_type comes from this class' __init__ argument # browser_version comes from ChromiumDriver's __init__, which calls my # edited chromium_version() method. log(f"Current {self.driver.chrome_type} version is {self.driver.browser_version}", first_line=True) # calls a DriverManager method that gets browser_version (e.g. 81.*, # 83.*, like above), driver_name, os_type, and driver_version (probably # "latest") from Driver. These are used to call DriverCache's # find_driver() method, which collects metadata from that class' # get_metadata() method to check if there's an existing driver in wdm's # cache and skip a download if so. if not, _get_driver_path continues on # to utils' download_file(), getting the URL from Driver's get_url() # method, which uses url, version, name, and os_type from this class' # init. (default output would be something like chromedriver.*googleapis.com/81.*/chromedriver_linux64.zip). # download_file uses requests and returns File(response). # _get_driver_path then uses DriverCache's save_file_to_cache method -- # BUT THIS IS WHAT WE WANT TO REPLACE! driver_path = self._get_driver_path(self.driver) os.chmod(driver_path, 0o755) # gives read/execute access to everyone and write access to root only # make symlink in directory where selenium will check for browser if self.driver.get_os_type() in { 'linux64', 'linux32', 'mac64', 'mac32' }: symlink_src = driver_path #actual_driver_filename equivalent,i think # Driver._name (from this class' init args) is equivalent to driver_filename symlink_target = os.path.join(self.link_path, self.driver.get_name()) if os.path.islink(symlink_target): if os.path.samefile(symlink_src, symlink_target): log("Symlink already exists: {0} -> {1}".format( symlink_target, symlink_src)) return tuple([symlink_src, symlink_target]) else: log("Symlink {0} already exists and will be overwritten.". format(symlink_target)) os.unlink(symlink_target) os.symlink(symlink_src, symlink_target) log("Created symlink: {0} -> {1}".format(symlink_target, symlink_src)) st = os.stat(symlink_src) os.chmod(symlink_src, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) return tuple([symlink_src, symlink_target])
def download_file(url: str) -> File: log(f"Trying to download new driver from {url}") response = requests.get(url, stream=True, timeout=20) validate_response(response) return File(response)
def download_driver(url): log(f"Trying to download new driver from {url}") response = requests.get(url, stream=True) validate_response(response) return response
def install(self): log(f"Current firefox version is {self.driver.browser_version}", first_line=True) return self._get_driver_path(self.driver)
def get_latest_release_version(self): log(f"Get LATEST driver version for {self.browser_version}") resp = requests.get(f"{self._latest_release_url}_{self.browser_version}") validate_response(resp) return resp.text.rstrip()