from contextlib import suppress from functools import cached_property, lru_cache import allure from allure_commons.types import AttachmentType from attr import attrib, attrs from requests import HTTPError, Session from ui_automation_framework.utils import CoreConfig from waiting import TimeoutExpired from app.src.helpers.waiting_wrapper import wait @attrs class BSAutomationSession: name = attrib() duration = attrib() os = attrib() os_version = attrib() browser_version = attrib() browser = attrib() device = attrib() status = attrib() hashed_id = attrib() reason = attrib() build_name = attrib() project_name = attrib() build_hashed_id = attrib() logs = attrib() browserstack_status = attrib() created_at = attrib() browser_url = attrib() public_url = attrib() video_url = attrib() appium_logs_url = attrib() device_logs_url = attrib() app_details = attrib() session_terminal_logs_url = attrib() build_terminal_logs_url = attrib() class BSApiClient: host = "https://api-cloud.browserstack.com" @cached_property def session(self): s = Session() s.auth = (CoreConfig.BROWSERSTACK_APP_USER, CoreConfig.BROWSERSTACK_APP_KEY) return s def get_network_logs(self, session_id): build_id = self.get_session_info(session_id).build_hashed_id r = self.session.get(f"{self.host}/app-automate/builds/{build_id}/sessions/{session_id}/networklogs") r.raise_for_status() return r.text def get_video(self, session_id): r = self.session.get(self.get_session_info(session_id).video_url) r.raise_for_status() if r.headers.get("Content-Type") == "video/mp4; charset=utf-8": return r.content @lru_cache def get_session_info(self, session_id): return BSAutomationSession(**self.session.get(f"https://api.browserstack.com/app-automate/sessions/{session_id}.json").json()["automation_session"]) def attach_video_and_logs(session_id): c = BSApiClient() with suppress(TimeoutExpired): logs = wait(lambda: c.get_network_logs(session_id), timeout=30, exceptions=HTTPError) allure.attach(logs, "Network logs", AttachmentType.TEXT) # with suppress(TimeoutExpired): # video_content = wait(lambda: c.get_video(session_id), timeout=30, exceptions=HTTPError) # allure.attach(video_content, "Session video", AttachmentType.MP4)