import json import os import requests from pathlib import Path from helpers.appium.driver_factory import create_driver class BrowserstackHelper: def __init__(self, username, key, mobile_os, app): self.app_url = self.get_app_url() self.username = username self.key = key self.mobile_os = mobile_os self.app = app self.build_id = None self.session_id = None self.api_gateway = "https://api-cloud.browserstack.com/app-automate" @staticmethod def get_app_url(): app_file = Path('app_url.txt') if app_file.is_file(): return app_file.read_text() return None def upload_app(self): if self.app_url is not None: return files = { 'file': (self.app, open(self.app, 'rb')), } response = requests.post( f"{self.api_gateway}/upload", files=files, auth=(self.username, self.key)) self.app_url = json.loads(response.text)["app_url"] f = open("app_url.txt", "w") f.write(self.app_url) f.close() def get_caps(self, feature): with open(f"browserstack_{self.mobile_os}_caps.json") as handle: caps_dict = json.loads(handle.read()) if os.getenv("BROWSERSTACK_BUILD_NAME"): caps_dict["name"] = feature caps_dict["build"] = os.getenv("BROWSERSTACK_BUILD_NAME") # if os.getenv("BROWSERSTACK_LOCAL_IDENTIFIER"): # caps_dict["browserstack.localIdentifier"] =\ # os.getenv("BROWSERSTACK_LOCAL_IDENTIFIER") if os.getenv("APPIUM_DEVICE") and os.getenv("OS_VERSION"): caps_dict["deviceName"] = os.environ["APPIUM_DEVICE"] # caps_dict["os_version"] = os.environ["OS_VERSION"] caps_dict["app"] = self.app_url print("Loading capabilities:") print(caps_dict) return caps_dict def start_browserstack_driver(self, context, feature): caps_dict = self.get_caps(feature) context.driver = create_driver( "https://hub.browserstack.com/wd/hub", caps_dict, mobile_os=self.mobile_os) self.get_build_id() self.get_session_id(context) @staticmethod def mark_test(failed, context): if failed is False: context.driver.execute_script( 'browserstack_executor: ' '{"action": "setSessionStatus", ' '"arguments": {"status":"passed", "reason": "Tests Passed"}}') else: context.driver.execute_script( 'browserstack_executor: ' '{"action": "setSessionStatus", ' '"arguments": {"status":"failed", "reason": "Tests Failing"}}') def get_build_id(self): build_url = self.api_gateway + "/builds.json" resp = requests.get(build_url, auth=(self.username, self.key)) if resp.status_code == 200: builds = resp.json() if builds and len(builds) > 0: self.build_id = builds[0]['automation_build']['hashed_id'] return self.build_id else: print('No builds found in BrowserStack response') self.build_id = None return None else: print('Failed to retrieve BS builds') print(resp.text) def get_session_id(self, context): self.session_id = json.loads(context.driver.execute_script( 'browserstack_executor:' ' {"action": "getSessionDetails"}'))['hashed_id'] print(f'[browserstack.py] Browserstack Session Id: {self.session_id}') def get_video(self): response = requests.get( f'{self.api_gateway}/sessions/{self.session_id}.json', auth=(self.username, self.key)) return response.json()['automation_session']['video_url'] def get_session_logs(self): session_log = requests.get( self.api_gateway + f'/builds/{self.build_id}/sessions/{self.session_id}/logs', auth=(self.username, self.key)).text return session_log def get_screenshot_url(self): session_log = self.get_session_logs() print(f'BS session log: \n{session_log}') screenshot_request = session_log.split('screenshot {}')[-1] response_result = screenshot_request.split('REQUEST')[0] image_url = response_result.split('https://')[-1] image_url = image_url.split('.png')[0] screenshot_url = image_url + '.png' return screenshot_url