Bug 1319024 - Sync default testing preferences for Marionette. r=automatedtester
authorHenrik Skupin <mail@hskupin.info>
Mon, 21 Nov 2016 16:18:58 +0100
changeset 324306 19c3f546ee34a93f7b8964bd2435f1d4784520f4
parent 324305 cc0e9c181248375cd2e409aa191b7d7c712cf1a0
child 324307 e4f46b2740b68703ac8fdcbc8871f889de5cbad8
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersautomatedtester
bugs1319024
milestone53.0a1
Bug 1319024 - Sync default testing preferences for Marionette. r=automatedtester MozReview-Commit-ID: 7fkpqCVYXIX
testing/marionette/client/marionette_driver/geckoinstance.py
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -12,46 +12,103 @@ from copy import deepcopy
 import mozversion
 
 from mozprofile import Profile
 from mozrunner import Runner, FennecEmulatorRunner
 
 
 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,
+        # 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
@@ -79,21 +136,21 @@ class GeckoInstance(object):
         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 != "-":
             if path is None:
-                path = 'gecko.log'
+                path = "gecko.log"
             elif os.path.isdir(path):
-                fname = 'gecko-{}.log'.format(time.time())
+                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
@@ -101,37 +158,37 @@ class GeckoInstance(object):
     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:
+        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
+            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()),
+                    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(
+                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)
 
@@ -151,40 +208,40 @@ class GeckoInstance(object):
 
     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()],
+            "processOutputLine": [NullOutput()],
         }
 
-        if self.gecko_log == '-':
-            process_args['stream'] = sys.stdout
+        if self.gecko_log == "-":
+            process_args["stream"] = sys.stdout
         else:
-            process_args['logfile'] = 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',
-                    'MOZ_CRASHREPORTER_SHUTDOWN': '1',
+        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
+            "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()
@@ -200,20 +257,47 @@ class GeckoInstance(object):
         if prefs:
             self.prefs = prefs
         else:
             self.prefs = None
         self.start()
 
 
 class FennecInstance(GeckoInstance):
+    fennec_prefs = {
+        # Enable output of dump()
+        "browser.dom.window.dump.enabled": True,
+
+        # Disable Android snippets
+        "browser.snippets.enabled": False,
+        "browser.snippets.syncPromo.enabled": False,
+        "browser.snippets.firstrunHomepage.enabled": False,
+
+        # Disable safebrowsing components
+        "browser.safebrowsing.downloads.enabled": False,
+
+        # Do not restore the last open set of tabs if the browser has crashed
+        "browser.sessionstore.resume_from_crash": False,
+
+        # Disable e10s by default
+        "browser.tabs.remote.autostart.1": False,
+        "browser.tabs.remote.autostart.2": False,
+        "browser.tabs.remote.autostart": False,
+
+        # Do not allow background tabs to be zombified, otherwise for tests that
+        # open additional tabs, the test harness tab itself might get unloaded
+        "browser.tabs.disableBackgroundZombification": True,
+    }
+
     def __init__(self, emulator_binary=None, avd_home=None, avd=None,
                  adb_path=None, serial=None, connect_to_running_emulator=False,
                  package_name=None, *args, **kwargs):
         super(FennecInstance, self).__init__(*args, **kwargs)
+        self.required_prefs.update(FennecInstance.fennec_prefs)
+
         self.runner_class = FennecEmulatorRunner
         # runner args
         self._package_name = package_name
         self.emulator_binary = emulator_binary
         self.avd_home = avd_home
         self.adb_path = adb_path
         self.avd = avd
         self.serial = serial
@@ -222,110 +306,150 @@ class FennecInstance(GeckoInstance):
     @property
     def package_name(self):
         """
         Name of app to run on emulator.
 
         Note that FennecInstance does not use self.binary
         """
         if self._package_name is None:
-            self._package_name = 'org.mozilla.fennec'
-            user = os.getenv('USER')
+            self._package_name = "org.mozilla.fennec"
+            user = os.getenv("USER")
             if user:
-                self._package_name += '_' + user
+                self._package_name += "_" + user
         return self._package_name
 
     def start(self):
         self._update_profile()
         self.runner = self.runner_class(**self._get_runner_args())
         try:
             if self.connect_to_running_emulator:
                 self.runner.device.connect()
             self.runner.start()
         except Exception as e:
             exc, val, tb = sys.exc_info()
-            message = 'Error possibly due to runner or device args: {}'
+            message = "Error possibly due to runner or device args: {}"
             raise exc, message.format(e.message), tb
         # gecko_log comes from logcat when running with device/emulator
         logcat_args = {
-            'filterspec': 'Gecko',
-            'serial': self.runner.device.dm._deviceSerial
+            "filterspec": "Gecko",
+            "serial": self.runner.device.dm._deviceSerial
         }
-        if self.gecko_log == '-':
-            logcat_args['stream'] = sys.stdout
+        if self.gecko_log == "-":
+            logcat_args["stream"] = sys.stdout
         else:
-            logcat_args['logfile'] = self.gecko_log
+            logcat_args["logfile"] = self.gecko_log
         self.runner.device.start_logcat(**logcat_args)
         self.runner.device.setup_port_forwarding(
             local_port=self.marionette_port,
             remote_port=self.marionette_port,
         )
 
     def _get_runner_args(self):
         process_args = {
-            'processOutputLine': [NullOutput()],
+            "processOutputLine": [NullOutput()],
         }
 
         runner_args = {
-            'app': self.package_name,
-            'avd_home': self.avd_home,
-            'adb_path': self.adb_path,
-            'binary': self.emulator_binary,
-            'profile': self.profile,
-            'cmdargs': ['-marionette'] + self.app_args,
-            'symbols_path': self.symbols_path,
-            'process_args': process_args,
-            'logdir': self.workspace or os.getcwd(),
-            'serial': self.serial,
+            "app": self.package_name,
+            "avd_home": self.avd_home,
+            "adb_path": self.adb_path,
+            "binary": self.emulator_binary,
+            "profile": self.profile,
+            "cmdargs": ["-marionette"] + self.app_args,
+            "symbols_path": self.symbols_path,
+            "process_args": process_args,
+            "logdir": self.workspace or os.getcwd(),
+            "serial": self.serial,
         }
         if self.avd:
-            runner_args['avd'] = self.avd
+            runner_args["avd"] = self.avd
 
         return runner_args
 
     def close(self, restart=False):
         super(FennecInstance, self).close(restart)
         if self.runner and self.runner.device.connected:
             self.runner.device.dm.remove_forward(
-                'tcp:{}'.format(int(self.marionette_port))
+                "tcp:{}".format(int(self.marionette_port))
             )
 
 
 class DesktopInstance(GeckoInstance):
     desktop_prefs = {
-        'app.update.auto': False,
-        'app.update.enabled': False,
-        'browser.dom.window.dump.enabled': True,
-        'browser.firstrun-content.dismissed': True,
-        # Bug 1145668 - Has to be reverted to about:blank once Marionette
-        # can correctly handle error pages
-        'browser.newtab.url': 'about:newtab',
-        'browser.newtabpage.enabled': False,
-        'browser.reader.detectedFirstArticle': True,
-        'browser.safebrowsing.blockedURIs.enabled': False,
-        'browser.safebrowsing.forbiddenURIs.enabled': False,
-        'browser.safebrowsing.malware.enabled': False,
-        'browser.safebrowsing.phishing.enabled': False,
-        'browser.search.update': False,
-        'browser.tabs.animate': False,
-        'browser.tabs.warnOnClose': False,
-        'browser.tabs.warnOnOpen': False,
-        'browser.uitour.enabled': False,
-        'extensions.getAddons.cache.enabled': False,
-        'extensions.installDistroAddons': False,
-        'extensions.showMismatchUI': False,
-        'extensions.update.enabled': False,
-        'extensions.update.notifyUser': False,
-        'geo.provider.testing': True,
-        'javascript.options.showInConsole': True,
-        'privacy.trackingprotection.enabled': False,
-        'privacy.trackingprotection.pbmode.enabled': False,
-        'security.notification_enable_delay': 0,
-        'signon.rememberSignons': False,
-        'toolkit.startup.max_resumed_crashes': -1,
+        # Disable application updates
+        "app.update.enabled": False,
+
+        # Enable output of dump()
+        "browser.dom.window.dump.enabled": True,
+
+        # Indicate that the download panel has been shown once so that whichever
+        # download test runs first doesn"t show the popup inconsistently
+        "browser.download.panel.shown": True,
+
+        # Do not show the EULA notification which can interfer with tests
+        "browser.EULA.override": True,
+
+        # Bug 1145668, 1312674
+        # Turn off once Marionette can correctly handle error pages, and doesn't
+        # hang when about:blank gets loaded twice
+        "browser.newtabpage.enabled": True,
+        # Assume the about:newtab page"s intro panels have been shown to not depend on
+        # which test runs first and happens to open about:newtab
+        "browser.newtabpage.introShown": True,
+
+        # Background thumbnails in particular cause grief, and disabling thumbnails
+        # in general can"t hurt - we re-enable them when tests need them
+        "browser.pagethumbnails.capturing_disabled": True,
+
+        # Avoid performing Reader Mode intros during tests
+        "browser.reader.detectedFirstArticle": True,
+
+        # Disable safebrowsing components
+        "browser.safebrowsing.blockedURIs.enabled": False,
+        "browser.safebrowsing.downloads.enabled": False,
+        "browser.safebrowsing.forbiddenURIs.enabled": False,
+        "browser.safebrowsing.malware.enabled": False,
+        "browser.safebrowsing.phishing.enabled": False,
+
+        # Disable updates to search engines
+        "browser.search.update": False,
+
+        # Do not restore the last open set of tabs if the browser has crashed
+        "browser.sessionstore.resume_from_crash": False,
+
+        # Don't check for the default web browser during startup
+        "browser.shell.checkDefaultBrowser": False,
+
+        # Disable e10s by default
+        "browser.tabs.remote.autostart.1": False,
+        "browser.tabs.remote.autostart.2": False,
+        "browser.tabs.remote.autostart": False,
+
+        # Needed for branded builds to prevent opening a second tab on startup
+        "browser.startup.homepage_override.mstone": "ignore",
+        # Start with a blank page by default
+        "browser.startup.page": 0,
+
+        # Disable tab animation
+        "browser.tabs.animate": False,
+
+        # Do not warn on exit when multiple tabs are open
+        "browser.tabs.warnOnClose": False,
+        # Do not warn when closing all other open tabs
+        "browser.tabs.warnOnCloseOtherTabs": False,
+        # Do not warn when multiple tabs will be opened
+        "browser.tabs.warnOnOpen": False,
+
+        # Disable the UI tour
+        "browser.uitour.enabled": False,
+
+        # Disable first-run welcome page
+        "startup.homepage_welcome_url": "about:blank",
+        "startup.homepage_welcome_url.additional": "",
     }
 
     def __init__(self, *args, **kwargs):
         super(DesktopInstance, self).__init__(*args, **kwargs)
         self.required_prefs.update(DesktopInstance.desktop_prefs)
 
 
 class NullOutput(object):