1# Copyright 2024 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from __future__ import annotations 6 7import datetime as dt 8from typing import TYPE_CHECKING, Optional 9 10from crossbench import path as pth 11from crossbench import plt 12from crossbench.browsers.splash_screen import SplashScreen 13from crossbench.browsers.viewport import Viewport 14from crossbench.flags.base import Flags, FlagsData 15from crossbench.flags.chrome import ChromeFlags 16from crossbench.network.live import LiveNetwork 17 18if TYPE_CHECKING: 19 from crossbench.cli.config.secrets import Secret, SecretsDict, SecretType 20 from crossbench.network.base import Network 21 22 23class Settings: 24 """Container object for browser agnostic settings.""" 25 26 def __init__(self, 27 flags: Optional[FlagsData] = None, 28 js_flags: Optional[FlagsData] = None, 29 cache_dir: Optional[pth.AnyPath] = None, 30 network: Optional[Network] = None, 31 driver_path: Optional[pth.AnyPath] = None, 32 viewport: Optional[Viewport] = None, 33 splash_screen: Optional[SplashScreen] = None, 34 platform: Optional[plt.Platform] = None, 35 secrets: Optional[SecretsDict] = None, 36 driver_logging: bool = False, 37 wipe_system_user_data: bool = False, 38 http_request_timeout: dt.timedelta = dt.timedelta()): 39 self._flags = self._convert_flags(flags, "flags") 40 self._js_flags = self._extract_js_flags(self._flags, js_flags) 41 self._cache_dir = cache_dir 42 self._platform = platform or plt.PLATFORM 43 self._driver_path = driver_path 44 self._network: Network = network or LiveNetwork() 45 self._viewport: Viewport = viewport or Viewport.DEFAULT 46 self._splash_screen: SplashScreen = splash_screen or SplashScreen.DEFAULT 47 self._secrets: SecretsDict = secrets or {} 48 self._driver_logging = driver_logging 49 self._wipe_system_user_data = wipe_system_user_data 50 self._http_request_timeout = http_request_timeout 51 52 def _extract_js_flags(self, flags: Flags, 53 js_flags: Optional[FlagsData]) -> Flags: 54 if isinstance(flags, ChromeFlags): 55 chrome_js_flags = flags.js_flags 56 if not js_flags: 57 return chrome_js_flags 58 if chrome_js_flags: 59 raise ValueError( 60 f"Ambiguous js-flags: flags.js_flags={repr(chrome_js_flags)}, " 61 f"js_flags={repr(js_flags)}") 62 return self._convert_flags(js_flags, "--js-flags") 63 64 def _convert_flags(self, flags: Optional[FlagsData], label: str) -> Flags: 65 if isinstance(flags, str): 66 raise ValueError(f"{label} should be a list, but got: {repr(flags)}") 67 if not flags: 68 return Flags() 69 if isinstance(flags, Flags): 70 return flags 71 return Flags(flags) 72 73 @property 74 def driver_logging(self) -> bool: 75 return self._driver_logging 76 77 @property 78 def flags(self) -> Flags: 79 return self._flags 80 81 @property 82 def js_flags(self) -> Flags: 83 return self._js_flags 84 85 @property 86 def cache_dir(self) -> Optional[pth.AnyPath]: 87 return self._cache_dir 88 89 @property 90 def driver_path(self) -> Optional[pth.AnyPath]: 91 return self._driver_path 92 93 @property 94 def platform(self) -> plt.Platform: 95 return self._platform 96 97 @property 98 def network(self) -> Network: 99 return self._network 100 101 @property 102 def secrets(self) -> SecretsDict: 103 return self._secrets 104 105 @property 106 def splash_screen(self) -> SplashScreen: 107 return self._splash_screen 108 109 @property 110 def wipe_system_user_data(self) -> bool: 111 return self._wipe_system_user_data 112 113 @property 114 def http_request_timeout(self) -> dt.timedelta: 115 return self._http_request_timeout 116 117 @property 118 def viewport(self) -> Viewport: 119 return self._viewport 120 121 @viewport.setter 122 def viewport(self, value: Viewport) -> None: 123 assert self._viewport.is_default 124 self._viewport = value 125