class GeckoInstance(object): required_prefs = { "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.tabs.remote.autostart": False, "browser.urlbar.userMadeSearchSuggestionsChoice": True, "browser.warnOnQuit": False, "datareporting.healthreport.logging.consoleEnabled": False, "datareporting.healthreport.service.enabled": False, "datareporting.healthreport.service.firstRun": False, "datareporting.healthreport.uploadEnabled": False, "datareporting.policy.dataSubmissionEnabled": False, "datareporting.policy.dataSubmissionPolicyAccepted": False, "dom.ipc.reportProcessHangs": False, # Only install add-ons from the profile and the application scope # Also ensure that those are not getting disabled. # see: https://developer.mozilla.org/en/Installing_extensions "extensions.enabledScopes": 5, "extensions.autoDisableScopes": 10, "focusmanager.testmode": True, "marionette.defaultPrefs.enabled": True, "startup.homepage_welcome_url": "", "startup.homepage_welcome_url.additional": "", "toolkit.telemetry.enabled": False, # Until Bug 1238095 is fixed, we have to enable CPOWs in order # for Marionette tests to work properly. "dom.ipc.cpows.forbid-unsafe-from-browser": False, } def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0): self.runner_class = Runner self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.binary = bin self.marionette_host = host self.marionette_port = port # Alternative to default temporary directory self.workspace = workspace self.addons = addons # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(self.required_prefs) if prefs: self.required_prefs.update(prefs) self._gecko_log_option = gecko_log self._gecko_log = None self.verbose = verbose @property def gecko_log(self): if self._gecko_log: return self._gecko_log path = self._gecko_log_option if path != '-': if path is None: path = 'gecko.log' elif os.path.isdir(path): fname = 'gecko-%d.log' % time.time() path = os.path.join(path, fname) path = os.path.realpath(path) if os.access(path, os.F_OK): os.remove(path) self._gecko_log = path return self._gecko_log def _update_profile(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args['profile'] = tempfile.mkdtemp( suffix='.mozrunner-{:.0f}'.format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = '{}-{:.0f}'.format( os.path.basename(self.profile_path), time.time() ) if self.workspace: profile_args["path_to"] = os.path.join(self.workspace, profile_name) self.profile = Profile.clone(**profile_args) def start(self): self._update_profile() self.runner = self.runner_class(**self._get_runner_args()) self.runner.start() def _get_runner_args(self): process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1'}) return { 'binary': self.binary, 'profile': self.profile, 'cmdargs': ['-no-remote', '-marionette'] + self.app_args, 'env': env, 'symbols_path': self.symbols_path, 'process_args': process_args } def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean and self.profile: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.displayedE10SPrompt": 5, "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.tabs.remote.autostart": False, "browser.urlbar.userMadeSearchSuggestionsChoice": True, "browser.warnOnQuit": False, "datareporting.healthreport.logging.consoleEnabled": False, "datareporting.healthreport.service.enabled": False, "datareporting.healthreport.service.firstRun": False, "datareporting.healthreport.uploadEnabled": False, "datareporting.policy.dataSubmissionEnabled": False, "datareporting.policy.dataSubmissionPolicyAccepted": False, "dom.ipc.reportProcessHangs": False, "focusmanager.testmode": True, "marionette.defaultPrefs.enabled": True, "startup.homepage_welcome_url": "about:blank", "toolkit.telemetry.enabled": False, } def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0): self.marionette_host = host self.marionette_port = port self.bin = bin # Alternative to default temporary directory self.workspace = workspace # Check if it is a Profile object or a path to profile self.profile = None self.addons = addons if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path if gecko_log != '-': if gecko_log is None: gecko_log = 'gecko.log' elif os.path.isdir(gecko_log): fname = 'gecko-%d.log' % time.time() gecko_log = os.path.join(gecko_log, fname) gecko_log = os.path.realpath(gecko_log) if os.access(gecko_log, os.F_OK): os.remove(gecko_log) self.gecko_log = gecko_log self.verbose = verbose def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args['profile'] = tempfile.mkdtemp( suffix='.mozrunner-{:.0f}'.format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = '{}-{:.0f}'.format( os.path.basename(self.profile_path), time.time() ) if self.workspace: profile_args["path_to"] = os.path.join(self.workspace, profile_name) self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ 'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner( binary=self.bin, profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { # Increase the APZ content response timeout in tests to 1 minute. # This is to accommodate the fact that test environments tends to be slower # than production environments (with the b2g emulator being the slowest of them # all), resulting in the production timeout value sometimes being exceeded # and causing false-positive test failures. See bug 1176798, bug 1177018, # bug 1210465. "apz.content_response_timeout": 60000, # Do not send Firefox health reports to the production server "datareporting.healthreport.documentServerURI": "http://%(server)s/dummy/healthreport/", "datareporting.healthreport.about.reportUrl": "http://%(server)s/dummy/abouthealthreport/", # Do not show datareporting policy notifications which can interfer with tests "datareporting.policy.dataSubmissionPolicyBypassNotification": True, "dom.ipc.reportProcessHangs": False, # No slow script dialogs "dom.max_chrome_script_run_time": 0, "dom.max_script_run_time": 0, # Only load extensions from the application and user profile # AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION "extensions.autoDisableScopes": 0, "extensions.enabledScopes": 5, # don't block add-ons for e10s "extensions.e10sBlocksEnabling": False, # Disable metadata caching for installed add-ons by default "extensions.getAddons.cache.enabled": False, # Disable intalling any distribution add-ons "extensions.installDistroAddons": False, "extensions.showMismatchUI": False, # Turn off extension updates so they don't bother tests "extensions.update.enabled": False, "extensions.update.notifyUser": False, # Make sure opening about:addons won"t hit the network "extensions.webservice.discoverURL": "http://%(server)s/dummy/discoveryURL", # Allow the application to have focus even it runs in the background "focusmanager.testmode": True, # Disable useragent updates "general.useragent.updates.enabled": False, # Always use network provider for geolocation tests # so we bypass the OSX dialog raised by the corelocation provider "geo.provider.testing": True, # Do not scan Wifi "geo.wifi.scan": False, # No hang monitor "hangmonitor.timeout": 0, "javascript.options.showInConsole": True, # Enable Marionette component # (deprecated and can be removed when Firefox 60 ships) "marionette.enabled": True, "marionette.defaultPrefs.enabled": True, # Disable recommended automation prefs in CI "marionette.prefs.recommended": False, "media.volume_scale": "0.01", # Do not prompt for temporary redirects "network.http.prompt-temp-redirect": False, # Disable speculative connections so they aren"t reported as leaking when they"re # hanging around "network.http.speculative-parallel-limit": 0, # Do not automatically switch between offline and online "network.manage-offline-status": False, # Make sure SNTP requests don't hit the network "network.sntp.pools": "%(server)s", # Tests don't wait for the notification button security delay "security.notification_enable_delay": 0, # Ensure blocklist updates don't hit the network "services.settings.server": "http://%(server)s/dummy/blocklist/", # Disable password capture, so that tests that include forms aren"t # influenced by the presence of the persistent doorhanger notification "signon.rememberSignons": False, # Prevent starting into safe mode after application crashes "toolkit.startup.max_resumed_crashes": -1, # We want to collect telemetry, but we don't want to send in the results "toolkit.telemetry.server": "https://%(server)s/dummy/telemetry/", # Enabling the support for File object creation in the content process. "dom.file.createInChild": True, } def __init__(self, host=None, port=None, bin=None, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0, headless=False): self.runner_class = Runner self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.binary = bin self.marionette_host = host self.marionette_port = port # Alternative to default temporary directory self.workspace = workspace self.addons = addons # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(self.required_prefs) if prefs: self.required_prefs.update(prefs) self._gecko_log_option = gecko_log self._gecko_log = None self.verbose = verbose self.headless = headless @property def gecko_log(self): if self._gecko_log: return self._gecko_log path = self._gecko_log_option if path != "-": if path is None: path = "gecko.log" elif os.path.isdir(path): fname = "gecko-{}.log".format(time.time()) path = os.path.join(path, fname) path = os.path.realpath(path) if os.access(path, os.F_OK): os.remove(path) self._gecko_log = path return self._gecko_log def _update_profile(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"][ "marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if "-jsdebugger" in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args["addons"] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args["profile"] = tempfile.mkdtemp( suffix=".mozrunner-{:.0f}".format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = "{}-{:.0f}".format( os.path.basename(self.profile_path), time.time()) if self.workspace: profile_args["path_to"] = os.path.join( self.workspace, profile_name) self.profile = Profile.clone(**profile_args) @classmethod def create(cls, app=None, *args, **kwargs): try: if not app and kwargs["bin"] is not None: app_id = mozversion.get_version( binary=kwargs["bin"])["application_id"] app = app_ids[app_id] instance_class = apps[app] except (IOError, KeyError): exc, val, tb = sys.exc_info() msg = 'Application "{0}" unknown (should be one of {1})' raise NotImplementedError, msg.format(app, apps.keys()), tb return instance_class(*args, **kwargs) def start(self): self._update_profile() self.runner = self.runner_class(**self._get_runner_args()) self.runner.start() def _get_runner_args(self): process_args = { "processOutputLine": [NullOutput()], } if self.gecko_log == "-": process_args["stream"] = sys.stdout else: process_args["logfile"] = self.gecko_log env = os.environ.copy() if self.headless: env["MOZ_HEADLESS"] = "1" env["DISPLAY"] = "77" # Set a fake display. # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ "MOZ_CRASHREPORTER": "1", "MOZ_CRASHREPORTER_NO_REPORT": "1", "MOZ_CRASHREPORTER_SHUTDOWN": "1", }) return { "binary": self.binary, "profile": self.profile, "cmdargs": ["-no-remote", "-marionette"] + self.app_args, "env": env, "symbols_path": self.symbols_path, "process_args": process_args } def close(self, clean=False): """ Close the managed Gecko process. Depending on self.runner_class, setting `clean` to True may also kill the emulator process in which this instance is running. :param clean: If True, also perform runner cleanup. """ if self.runner: self.runner.stop() if clean: self.runner.cleanup() if clean and self.profile: self.profile.cleanup() self.profile = None def restart(self, prefs=None, clean=True): """ Close then start the managed Gecko process. :param prefs: Dictionary of preference names and values. :param clean: If True, reset the profile before starting. """ self.close(clean=clean) if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, # Needed for branded builds to prevent opening a second tab on startup "browser.startup.homepage_override.mstone": "ignore", "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.tabs.remote.autostart": False, "browser.urlbar.userMadeSearchSuggestionsChoice": True, "browser.warnOnQuit": False, "datareporting.healthreport.logging.consoleEnabled": False, "datareporting.healthreport.service.enabled": False, "datareporting.healthreport.service.firstRun": False, "datareporting.healthreport.uploadEnabled": False, "datareporting.policy.dataSubmissionEnabled": False, "datareporting.policy.dataSubmissionPolicyAccepted": False, "dom.ipc.reportProcessHangs": False, # Only install add-ons from the profile and the application scope # Also ensure that those are not getting disabled. # see: https://developer.mozilla.org/en/Installing_extensions "extensions.enabledScopes": 5, "extensions.autoDisableScopes": 10, "focusmanager.testmode": True, "marionette.defaultPrefs.enabled": True, "startup.homepage_welcome_url": "", "startup.homepage_welcome_url.additional": "", "toolkit.telemetry.enabled": False, # Until Bug 1238095 is fixed, we have to enable CPOWs in order # for Marionette tests to work properly. "dom.ipc.cpows.forbid-unsafe-from-browser": False, } def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0): self.runner_class = Runner self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.binary = bin self.marionette_host = host self.marionette_port = port # Alternative to default temporary directory self.workspace = workspace self.addons = addons # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(self.required_prefs) if prefs: self.required_prefs.update(prefs) self._gecko_log_option = gecko_log self._gecko_log = None self.verbose = verbose @property def gecko_log(self): if self._gecko_log: return self._gecko_log path = self._gecko_log_option if path != '-': if path is None: path = 'gecko.log' elif os.path.isdir(path): fname = 'gecko-{}.log'.format(time.time()) path = os.path.join(path, fname) path = os.path.realpath(path) if os.access(path, os.F_OK): os.remove(path) self._gecko_log = path return self._gecko_log def _update_profile(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args['profile'] = tempfile.mkdtemp( suffix='.mozrunner-{:.0f}'.format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = '{}-{:.0f}'.format( os.path.basename(self.profile_path), time.time() ) if self.workspace: profile_args["path_to"] = os.path.join(self.workspace, profile_name) self.profile = Profile.clone(**profile_args) def start(self): self._update_profile() self.runner = self.runner_class(**self._get_runner_args()) self.runner.start() def _get_runner_args(self): process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_SHUTDOWN': '1', }) return { 'binary': self.binary, 'profile': self.profile, 'cmdargs': ['-no-remote', '-marionette'] + self.app_args, 'env': env, 'symbols_path': self.symbols_path, 'process_args': process_args } def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean and self.profile: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "marionette.defaultPrefs.enabled": True, "marionette.logging": True, "browser.displayedE10SPrompt": 5, "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.warnOnQuit": False, "dom.ipc.reportProcessHangs": False, "focusmanager.testmode": True, "startup.homepage_welcome_url": "about:blank" } def __init__(self, host, port, bin, profile=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None): self.marionette_host = host self.marionette_port = port self.bin = bin # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.gecko_log = gecko_log def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"][ "marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: if self.gecko_log is None: self.gecko_log = 'gecko.log' elif os.path.isdir(self.gecko_log): fname = "gecko-%d.log" % time.time() self.gecko_log = os.path.join(self.gecko_log, fname) self.gecko_log = os.path.realpath(self.gecko_log) if os.access(self.gecko_log, os.F_OK): if platform.system() is 'Windows': # NOTE: windows has a weird filesystem where it happily 'closes' # the file, but complains if you try to delete it. You get a # 'file still in use' error. Sometimes you can wait a bit and # a retry will succeed. # If all retries fail, we'll just continue without removing # the file. In this case, if we are restarting the instance, # then the new logs just get appended to the old file. tries = 0 while tries < 10: try: os.remove(self.gecko_log) break except WindowsError as e: if e.errno == errno.EACCES: tries += 1 time.sleep(0.5) else: raise e else: os.remove(self.gecko_log) process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ 'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner(binary=self.bin, profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "marionette.defaultPrefs.enabled": True, "marionette.logging": True, "browser.displayedE10SPrompt": 5, "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.warnOnQuit": False, "dom.ipc.reportProcessHangs": False, "focusmanager.testmode": True, "startup.homepage_welcome_url": "about:blank" } def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None): self.marionette_host = host self.marionette_port = port self.bin = bin # Check if it is a Profile object or a path to profile self.profile = None self.addons = addons if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path if gecko_log != '-': if gecko_log is None: gecko_log = 'gecko.log' elif os.path.isdir(gecko_log): fname = 'gecko-%d.log' % time.time() gecko_log = os.path.join(gecko_log, fname) gecko_log = os.path.realpath(gecko_log) if os.access(gecko_log, os.F_OK): os.remove(gecko_log) self.gecko_log = gecko_log def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"][ "marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ 'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner(binary=self.bin, profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = {"marionette.defaultPrefs.enabled": True, "marionette.logging": True, "browser.displayedE10SPrompt": 5, "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.warnOnQuit": False, "dom.ipc.reportProcessHangs": False, "focusmanager.testmode": True, "startup.homepage_welcome_url": "about:blank"} def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None): self.marionette_host = host self.marionette_port = port self.bin = bin # Check if it is a Profile object or a path to profile self.profile = None self.addons = addons if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path if gecko_log != '-': if gecko_log is None: gecko_log = 'gecko.log' elif os.path.isdir(gecko_log): fname = 'gecko-%d.log' % time.time() gecko_log = os.path.join(gecko_log, fname) gecko_log = os.path.realpath(gecko_log) if os.access(gecko_log, os.F_OK): os.remove(gecko_log) self.gecko_log = gecko_log def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ 'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner( binary=self.bin, profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "marionette.defaultPrefs.enabled": True, "marionette.logging": True, "startup.homepage_welcome_url": "about:blank", "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.sessionstore.resume_from_crash": False, "browser.warnOnQuit": False, "browser.displayedE10SPrompt": 5, "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "dom.ipc.reportProcessHangs": False, } def __init__(self, host, port, bin, profile=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None): self.marionette_host = host self.marionette_port = port self.bin = bin # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.gecko_log = gecko_log def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if "-jsdebugger" in self.app_args: profile_args["preferences"].update( { "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.debugger.chrome-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, } ) if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: profile_args["restore"] = False self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path self.profile = Profile.clone(**profile_args) process_args = {"processOutputLine": [NullOutput()]} if self.gecko_log == "-": process_args["stream"] = sys.stdout else: if self.gecko_log is None: self.gecko_log = "gecko.log" elif os.path.isdir(self.gecko_log): fname = "gecko-%d.log" % time.time() self.gecko_log = os.path.join(self.gecko_log, fname) self.gecko_log = os.path.realpath(self.gecko_log) if os.access(self.gecko_log, os.F_OK): if platform.system() is "Windows": # NOTE: windows has a weird filesystem where it happily 'closes' # the file, but complains if you try to delete it. You get a # 'file still in use' error. Sometimes you can wait a bit and # a retry will succeed. # If all retries fail, we'll just continue without removing # the file. In this case, if we are restarting the instance, # then the new logs just get appended to the old file. tries = 0 while tries < 10: try: os.remove(self.gecko_log) break except WindowsError as e: if e.errno == errno.EACCES: tries += 1 time.sleep(0.5) else: raise e else: os.remove(self.gecko_log) process_args["logfile"] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({"MOZ_CRASHREPORTER": "1", "MOZ_CRASHREPORTER_NO_REPORT": "1"}) self.runner = Runner( binary=self.bin, profile=self.profile, cmdargs=["-no-remote", "-marionette"] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args, ) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): if clean: self.profile.cleanup() self.profile = None self.close(restart=True) if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "browser.displayedE10SPrompt.1": 5, "browser.displayedE10SPrompt.2": 5, "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.displayedE10SPrompt": 5, "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.tabs.remote.autostart": False, "browser.urlbar.userMadeSearchSuggestionsChoice": True, "browser.warnOnQuit": False, "datareporting.healthreport.logging.consoleEnabled": False, "datareporting.healthreport.service.enabled": False, "datareporting.healthreport.service.firstRun": False, "datareporting.healthreport.uploadEnabled": False, "datareporting.policy.dataSubmissionEnabled": False, "datareporting.policy.dataSubmissionPolicyAccepted": False, "dom.ipc.reportProcessHangs": False, "focusmanager.testmode": True, "marionette.defaultPrefs.enabled": True, "startup.homepage_welcome_url": "about:blank", "toolkit.telemetry.enabled": False, # Until Bug 1238095 is fixed, we have to enable CPOWs in order # for Marionette tests to work properly. "dom.ipc.cpows.forbid-unsafe-from-browser": False, } def __init__(self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0): self.marionette_host = host self.marionette_port = port self.bin = bin # Alternative to default temporary directory self.workspace = workspace # Check if it is a Profile object or a path to profile self.profile = None self.addons = addons if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path if gecko_log != '-': if gecko_log is None: gecko_log = 'gecko.log' elif os.path.isdir(gecko_log): fname = 'gecko-%d.log' % time.time() gecko_log = os.path.join(gecko_log, fname) gecko_log = os.path.realpath(gecko_log) if os.access(gecko_log, os.F_OK): os.remove(gecko_log) self.gecko_log = gecko_log self.verbose = verbose def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"][ "marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if '-jsdebugger' in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args['addons'] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args['profile'] = tempfile.mkdtemp( suffix='.mozrunner-{:.0f}'.format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = '{}-{:.0f}'.format( os.path.basename(self.profile_path), time.time()) if self.workspace: profile_args["path_to"] = os.path.join( self.workspace, profile_name) self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], } if self.gecko_log == '-': process_args['stream'] = sys.stdout else: process_args['logfile'] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({ 'MOZ_CRASHREPORTER': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner(binary=self.bin, profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { # Increase the APZ content response timeout in tests to 1 minute. # This is to accommodate the fact that test environments tends to be slower # than production environments (with the b2g emulator being the slowest of them # all), resulting in the production timeout value sometimes being exceeded # and causing false-positive test failures. See bug 1176798, bug 1177018, # bug 1210465. "apz.content_response_timeout": 60000, # Do not send Firefox health reports to the production server "datareporting.healthreport.documentServerURI": "http://%(server)s/dummy/healthreport/", "datareporting.healthreport.about.reportUrl": "http://%(server)s/dummy/abouthealthreport/", # Do not show datareporting policy notifications which can interfer with tests "datareporting.policy.dataSubmissionPolicyBypassNotification": True, # Until Bug 1238095 is fixed, we have to enable CPOWs in order # for Marionette tests to work properly. "dom.ipc.cpows.forbid-unsafe-from-browser": False, "dom.ipc.reportProcessHangs": False, # No slow script dialogs "dom.max_chrome_script_run_time": 0, "dom.max_script_run_time": 0, # Only load extensions from the application and user profile # AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION "extensions.autoDisableScopes": 0, "extensions.enabledScopes": 5, # don't block add-ons for e10s "extensions.e10sBlocksEnabling": False, # Disable metadata caching for installed add-ons by default "extensions.getAddons.cache.enabled": False, # Disable intalling any distribution add-ons "extensions.installDistroAddons": False, "extensions.showMismatchUI": False, # Turn off extension updates so they don't bother tests "extensions.update.enabled": False, "extensions.update.notifyUser": False, # Make sure opening about:addons won"t hit the network "extensions.webservice.discoverURL": "http://%(server)s/dummy/discoveryURL", # Allow the application to have focus even it runs in the background "focusmanager.testmode": True, # Disable useragent updates "general.useragent.updates.enabled": False, # Always use network provider for geolocation tests # so we bypass the OSX dialog raised by the corelocation provider "geo.provider.testing": True, # Do not scan Wifi "geo.wifi.scan": False, # No hang monitor "hangmonitor.timeout": 0, "javascript.options.showInConsole": True, "marionette.defaultPrefs.enabled": True, "media.volume_scale": "0.01", # Make sure the disk cache doesn't get auto disabled "network.http.bypass-cachelock-threshold": 200000, # Do not prompt for temporary redirects "network.http.prompt-temp-redirect": False, # Disable speculative connections so they aren"t reported as leaking when they"re # hanging around "network.http.speculative-parallel-limit": 0, # Do not automatically switch between offline and online "network.manage-offline-status": False, # Make sure SNTP requests don't hit the network "network.sntp.pools": "%(server)s", # Tests don't wait for the notification button security delay "security.notification_enable_delay": 0, # Ensure blocklist updates don't hit the network "services.settings.server": "http://%(server)s/dummy/blocklist/", # Disable password capture, so that tests that include forms aren"t # influenced by the presence of the persistent doorhanger notification "signon.rememberSignons": False, # Prevent starting into safe mode after application crashes "toolkit.startup.max_resumed_crashes": -1, # We want to collect telemetry, but we don't want to send in the results "toolkit.telemetry.server": "https://%(server)s/dummy/telemetry/", } def __init__(self, host=None, port=None, bin=None, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0): self.runner_class = Runner self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path self.binary = bin self.marionette_host = host self.marionette_port = port # Alternative to default temporary directory self.workspace = workspace self.addons = addons # Check if it is a Profile object or a path to profile self.profile = None if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(self.required_prefs) if prefs: self.required_prefs.update(prefs) self._gecko_log_option = gecko_log self._gecko_log = None self.verbose = verbose @property def gecko_log(self): if self._gecko_log: return self._gecko_log path = self._gecko_log_option if path != "-": if path is None: path = "gecko.log" elif os.path.isdir(path): fname = "gecko-{}.log".format(time.time()) path = os.path.join(path, fname) path = os.path.realpath(path) if os.access(path, os.F_OK): os.remove(path) self._gecko_log = path return self._gecko_log def _update_profile(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if "-jsdebugger" in self.app_args: profile_args["preferences"].update({ "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, }) if self.addons: profile_args["addons"] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args["profile"] = tempfile.mkdtemp( suffix=".mozrunner-{:.0f}".format(time.time()), dir=self.workspace) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = "{}-{:.0f}".format( os.path.basename(self.profile_path), time.time() ) if self.workspace: profile_args["path_to"] = os.path.join(self.workspace, profile_name) self.profile = Profile.clone(**profile_args) @classmethod def create(cls, app=None, *args, **kwargs): try: if not app: app_id = mozversion.get_version(binary=kwargs.get('bin'))['application_id'] app = app_ids[app_id] instance_class = apps[app] except KeyError: msg = 'Application "{0}" unknown (should be one of {1})' raise NotImplementedError(msg.format(app, apps.keys())) return instance_class(*args, **kwargs) def start(self): self._update_profile() self.runner = self.runner_class(**self._get_runner_args()) self.runner.start() def _get_runner_args(self): process_args = { "processOutputLine": [NullOutput()], } if self.gecko_log == "-": process_args["stream"] = sys.stdout else: process_args["logfile"] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({"MOZ_CRASHREPORTER": "1", "MOZ_CRASHREPORTER_NO_REPORT": "1", "MOZ_CRASHREPORTER_SHUTDOWN": "1", }) return { "binary": self.binary, "profile": self.profile, "cmdargs": ["-no-remote", "-marionette"] + self.app_args, "env": env, "symbols_path": self.symbols_path, "process_args": process_args } def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean and self.profile: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()
class GeckoInstance(object): required_prefs = { "browser.sessionstore.resume_from_crash": False, "browser.shell.checkDefaultBrowser": False, "browser.startup.page": 0, "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False, "browser.tabs.remote.autostart": False, "browser.urlbar.userMadeSearchSuggestionsChoice": True, "browser.warnOnQuit": False, "datareporting.healthreport.logging.consoleEnabled": False, "datareporting.healthreport.service.enabled": False, "datareporting.healthreport.service.firstRun": False, "datareporting.healthreport.uploadEnabled": False, "datareporting.policy.dataSubmissionEnabled": False, "datareporting.policy.dataSubmissionPolicyAccepted": False, "dom.ipc.reportProcessHangs": False, # Only install add-ons from the profile and the application scope # Also ensure that those are not getting disabled. # see: https://developer.mozilla.org/en/Installing_extensions "extensions.enabledScopes": 5, "extensions.autoDisableScopes": 10, "focusmanager.testmode": True, "marionette.defaultPrefs.enabled": True, "startup.homepage_welcome_url": "about:blank", "toolkit.telemetry.enabled": False, # Until Bug 1238095 is fixed, we have to enable CPOWs in order # for Marionette tests to work properly. "dom.ipc.cpows.forbid-unsafe-from-browser": False, } def __init__( self, host, port, bin, profile=None, addons=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None, workspace=None, verbose=0, ): self.marionette_host = host self.marionette_port = port self.bin = bin # Alternative to default temporary directory self.workspace = workspace # Check if it is a Profile object or a path to profile self.profile = None self.addons = addons if isinstance(profile, Profile): self.profile = profile else: self.profile_path = profile self.prefs = prefs self.required_prefs = deepcopy(GeckoInstance.required_prefs) if prefs: self.required_prefs.update(prefs) self.app_args = app_args or [] self.runner = None self.symbols_path = symbols_path if gecko_log != "-": if gecko_log is None: gecko_log = "gecko.log" elif os.path.isdir(gecko_log): fname = "gecko-%d.log" % time.time() gecko_log = os.path.join(gecko_log, fname) gecko_log = os.path.realpath(gecko_log) if os.access(gecko_log, os.F_OK): os.remove(gecko_log) self.gecko_log = gecko_log self.verbose = verbose def start(self): profile_args = {"preferences": deepcopy(self.required_prefs)} profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) if self.verbose: level = "TRACE" if self.verbose >= 2 else "DEBUG" profile_args["preferences"]["marionette.logging"] = level if "-jsdebugger" in self.app_args: profile_args["preferences"].update( { "devtools.browsertoolbox.panel": "jsdebugger", "devtools.debugger.remote-enabled": True, "devtools.chrome.enabled": True, "devtools.debugger.prompt-connection": False, "marionette.debugging.clicktostart": True, } ) if self.addons: profile_args["addons"] = self.addons if hasattr(self, "profile_path") and self.profile is None: if not self.profile_path: if self.workspace: profile_args["profile"] = tempfile.mkdtemp( suffix=".mozrunner-{:.0f}".format(time.time()), dir=self.workspace ) self.profile = Profile(**profile_args) else: profile_args["path_from"] = self.profile_path profile_name = "{}-{:.0f}".format(os.path.basename(self.profile_path), time.time()) if self.workspace: profile_args["path_to"] = os.path.join(self.workspace, profile_name) self.profile = Profile.clone(**profile_args) process_args = {"processOutputLine": [NullOutput()]} if self.gecko_log == "-": process_args["stream"] = sys.stdout else: process_args["logfile"] = self.gecko_log env = os.environ.copy() # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting env.update({"MOZ_CRASHREPORTER": "1", "MOZ_CRASHREPORTER_NO_REPORT": "1"}) self.runner = Runner( binary=self.bin, profile=self.profile, cmdargs=["-no-remote", "-marionette"] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args, ) self.runner.start() def close(self, restart=False): if not restart: self.profile = None if self.runner: self.runner.stop() self.runner.cleanup() def restart(self, prefs=None, clean=True): self.close(restart=True) if clean: self.profile.cleanup() self.profile = None if prefs: self.prefs = prefs else: self.prefs = None self.start()