From 187fb9b8b234b8be6bec39922d0e99935eafa6f2 Mon Sep 17 00:00:00 2001 From: amaanbs Date: Fri, 6 Jun 2025 07:12:26 +0530 Subject: [PATCH 1/5] change binary download distribution --- browserstack/local.py | 7 ++++++- browserstack/local_binary.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/browserstack/local.py b/browserstack/local.py index 3dd5d1a..544c791 100644 --- a/browserstack/local.py +++ b/browserstack/local.py @@ -73,7 +73,12 @@ def start(self, **kwargs): self.binary_path = self.options['binarypath'] del self.options['binarypath'] else: - self.binary_path = LocalBinary().get_binary() + l = LocalBinary(self.key) + try: + self.binary_path = l.get_binary() + except Exception as e: + l = LocalBinary(self.key, e) + self.binary_path = l.get_binary() if 'logfile' in self.options: self.local_logfile_path = self.options['logfile'] diff --git a/browserstack/local_binary.py b/browserstack/local_binary.py index 72d1402..11c6ef0 100644 --- a/browserstack/local_binary.py +++ b/browserstack/local_binary.py @@ -1,6 +1,7 @@ import platform, os, sys, stat, tempfile, re, subprocess from browserstack.bserrors import BrowserStackLocalError import gzip +import json try: from urllib.request import urlopen, Request @@ -10,11 +11,13 @@ class LocalBinary: _version = None - def __init__(self): + def __init__(self, key, error_object=None): + self.key = key + self.error_object = error_object is_64bits = sys.maxsize > 2**32 self.is_windows = False osname = platform.system() - source_url = "https://www.browserstack.com/local-testing/downloads/binaries/" + source_url = self.fetch_source_url() + '/' if osname == 'Darwin': self.http_path = source_url + "BrowserStackLocal-darwin-x64" @@ -37,6 +40,31 @@ def __init__(self): ] self.path_index = 0 + def fetch_source_url(self): + url = "https://local.browserstack.com/binary/api/v1/endpoint" + headers = { + "Content-Type": "application/json", + "Accept": "application/json" + } + data = {"auth_token": self.key} + + if self.error_object is not None: + data["error_message"] = str(self.error_object) + headers["X-Local-Fallback-Cloudflare"] = "true" + + req = Request(url, data=json.dumps(data).encode("utf-8")) + for key, value in headers.items(): + req.add_header(key, value) + + try: + with urlopen(req) as response: + resp_bytes = response.read() + resp_str = resp_bytes.decode('utf-8') + resp_json = json.loads(resp_str) + return resp_json["data"]["endpoint"] + except Exception as e: + raise BrowserStackLocalError('Error trying to fetch the source url for downloading the binary: {}'.format(e)) + @staticmethod def set_version(version): LocalBinary._version = version From baa2960d44a292fe8015d229540d99947432d9e6 Mon Sep 17 00:00:00 2001 From: amaanbs Date: Tue, 10 Jun 2025 02:42:50 +0530 Subject: [PATCH 2/5] minor fixes --- browserstack/local.py | 5 +++-- browserstack/local_binary.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/browserstack/local.py b/browserstack/local.py index 544c791..3e3fa54 100644 --- a/browserstack/local.py +++ b/browserstack/local.py @@ -50,10 +50,11 @@ def get_package_version(self): return version def _generate_cmd(self): - cmd = [self.binary_path, '-d', 'start', '-logFile', self.local_logfile_path, "-k", self.key, '--source', 'python:' + self.get_package_version()] + cmd = [self.binary_path, '-d', 'start', '-logFile', self.local_logfile_path, "-k", self.key, '--source', 'python:' + self.get_package_version(), '--bs-host "k8s-devlocal.bsstag.com"'] for o in self.options.keys(): if self.options.get(o) is not None: cmd = cmd + self.__xstr(o, self.options.get(o)) + print(">>> CMD : ", cmd) return cmd def _generate_stop_cmd(self): @@ -101,7 +102,7 @@ def start(self, **kwargs): output_string = err.decode() data = json.loads(output_string) - + print(">>> DATA : ", data) if data['state'] != "connected": raise BrowserStackLocalError(data["message"]["message"]) else: diff --git a/browserstack/local_binary.py b/browserstack/local_binary.py index 11c6ef0..14ca29c 100644 --- a/browserstack/local_binary.py +++ b/browserstack/local_binary.py @@ -89,7 +89,7 @@ def __available_dir(self): return final_path else: self.path_index += 1 - raise BrowserStackLocalError('Error trying to download BrowserStack Local binary') + raise BrowserStackLocalError('Error trying to download BrowserStack Local binary, exhausted user directories to download to.') def download(self, chunk_size=8192, progress_hook=None): headers = { @@ -108,6 +108,7 @@ def download(self, chunk_size=8192, progress_hook=None): total_size = int(response.info().get_all('Content-Length')[0].strip() or '0') bytes_so_far = 0 + # Limits retries to the number of directories dest_parent_dir = self.__available_dir() dest_binary_name = 'BrowserStackLocal' if self.is_windows: From 70f76a5cb09acdb07d97a0d41f74057a281a330c Mon Sep 17 00:00:00 2001 From: amaanbs Date: Tue, 10 Jun 2025 02:44:02 +0530 Subject: [PATCH 3/5] fixes --- browserstack/local.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browserstack/local.py b/browserstack/local.py index 3e3fa54..1ebb8e4 100644 --- a/browserstack/local.py +++ b/browserstack/local.py @@ -50,7 +50,7 @@ def get_package_version(self): return version def _generate_cmd(self): - cmd = [self.binary_path, '-d', 'start', '-logFile', self.local_logfile_path, "-k", self.key, '--source', 'python:' + self.get_package_version(), '--bs-host "k8s-devlocal.bsstag.com"'] + cmd = [self.binary_path, '-d', 'start', '-logFile', self.local_logfile_path, "-k", self.key, '--source', 'python:' + self.get_package_version()] for o in self.options.keys(): if self.options.get(o) is not None: cmd = cmd + self.__xstr(o, self.options.get(o)) @@ -102,7 +102,7 @@ def start(self, **kwargs): output_string = err.decode() data = json.loads(output_string) - print(">>> DATA : ", data) + if data['state'] != "connected": raise BrowserStackLocalError(data["message"]["message"]) else: From 2482e0e0d1d7c82a3e75b4c8011a626a181a5d63 Mon Sep 17 00:00:00 2001 From: amaanbs Date: Tue, 10 Jun 2025 02:45:21 +0530 Subject: [PATCH 4/5] fixes --- browserstack/local.py | 1 - 1 file changed, 1 deletion(-) diff --git a/browserstack/local.py b/browserstack/local.py index 1ebb8e4..544c791 100644 --- a/browserstack/local.py +++ b/browserstack/local.py @@ -54,7 +54,6 @@ def _generate_cmd(self): for o in self.options.keys(): if self.options.get(o) is not None: cmd = cmd + self.__xstr(o, self.options.get(o)) - print(">>> CMD : ", cmd) return cmd def _generate_stop_cmd(self): From f66802718d765a0fd24236b9264549e60ae75fcf Mon Sep 17 00:00:00 2001 From: amaanbs Date: Tue, 17 Jun 2025 20:01:23 +0530 Subject: [PATCH 5/5] Version bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 83ea1ef..bdcd2b7 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name = 'browserstack-local', packages = ['browserstack'], - version = '1.2.10', + version = '1.2.11', description = 'Python bindings for Browserstack Local', long_description=open('README.md').read(), long_description_content_type='text/markdown',