Bug 1291687 - Ensure string formatting is using `format()` instead of `%` for all Marionette py files: r?whimboo r?maja_zf draft
authorFrancesco Pischedda <francesco.pischedda@gmail.com>
Wed, 28 Sep 2016 21:39:00 +0200
changeset 422096 a87bc0dfae0a652a7e6c6bca70552a97422b05db
parent 421960 4b9944879c9a60a9aba4a744a7401bc38e0f39c4
child 533259 7200670684f68e83580e435c42adb49470015529
push id31691
push userbmo:francesco.pischedda@gmail.com
push dateFri, 07 Oct 2016 13:02:26 +0000
reviewerswhimboo, maja_zf
bugs1291687
milestone52.0a1
Bug 1291687 - Ensure string formatting is using `format()` instead of `%` for all Marionette py files: r?whimboo r?maja_zf MozReview-Commit-ID: LdB3uvuqva0
testing/marionette/client/marionette_driver/addons.py
testing/marionette/client/marionette_driver/errors.py
testing/marionette/client/marionette_driver/geckoinstance.py
testing/marionette/client/marionette_driver/marionette.py
testing/marionette/client/marionette_driver/selection.py
testing/marionette/client/marionette_driver/transport.py
testing/marionette/client/marionette_driver/wait.py
testing/marionette/harness/marionette/marionette_test/decorators.py
testing/marionette/harness/marionette/marionette_test/testcases.py
testing/marionette/harness/marionette/runner/base.py
testing/marionette/harness/marionette/runner/httpd.py
testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/client.py
testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/server.py
testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/webdriver_event_listener.py
testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/test/test_webdriver.py
testing/marionette/harness/marionette/runner/mixins/browsermob.py
testing/marionette/harness/marionette/runner/mixins/endurance.py
testing/marionette/harness/marionette/runner/mixins/reporting.py
testing/marionette/harness/marionette/runner/mixins/xmlgen.py
testing/marionette/harness/marionette/tests/unit/test_capabilities.py
testing/marionette/harness/marionette/tests/unit/test_click_scrolling.py
testing/marionette/harness/marionette/tests/unit/test_cookies.py
testing/marionette/harness/marionette/tests/unit/test_element_retrieval.py
testing/marionette/harness/marionette/tests/unit/test_element_state.py
testing/marionette/harness/marionette/tests/unit/test_errors.py
testing/marionette/harness/marionette/tests/unit/test_execute_async_script.py
testing/marionette/harness/marionette/tests/unit/test_execute_isolate.py
testing/marionette/harness/marionette/tests/unit/test_execute_script.py
testing/marionette/harness/marionette/tests/unit/test_expected.py
testing/marionette/harness/marionette/tests/unit/test_file_upload.py
testing/marionette/harness/marionette/tests/unit/test_gesture.py
testing/marionette/harness/marionette/tests/unit/test_getactiveframe_oop.py
testing/marionette/harness/marionette/tests/unit/test_import_script.py
testing/marionette/harness/marionette/tests/unit/test_proxy.py
testing/marionette/harness/marionette/tests/unit/test_screen_orientation.py
testing/marionette/harness/marionette/tests/unit/test_screenshot.py
testing/marionette/harness/marionette/tests/unit/test_select.py
testing/marionette/harness/marionette/tests/unit/test_set_window_size.py
testing/marionette/harness/marionette/tests/unit/test_switch_remote_frame.py
testing/marionette/harness/marionette/tests/unit/test_transport.py
testing/marionette/harness/marionette/tests/unit/test_typing.py
testing/marionette/harness/marionette/tests/unit/test_wait.py
testing/marionette/harness/session/runner/base.py
testing/marionette/harness/session/runner/ping_server.py
testing/marionette/harness/session/session_test.py
--- a/testing/marionette/client/marionette_driver/addons.py
+++ b/testing/marionette/client/marionette_driver/addons.py
@@ -87,17 +87,18 @@ class Addons(object):
                 AddonManager.addAddonListener(listener);
                 AddonManager.installTemporaryAddon(file);
               }
             """, script_args=[path, temp], debug_script=True)
 
         if status:
             if status in ADDON_INSTALL_ERRORS:
                 raise AddonInstallException(ADDON_INSTALL_ERRORS[status])
-            raise AddonInstallException("Addon failed to install with return code: %d" % status)
+            raise AddonInstallException(
+                "Addon failed to install with return code: {}".format(status))
         return addon_id
 
     def uninstall(self, addon_id):
         """Uninstall an addon.
 
         If the addon is restartless, it will be uninstalled right away.
         Otherwise a restart using :func:`~marionette_driver.marionette.Marionette.restart`
         will be needed.
--- a/testing/marionette/client/marionette_driver/errors.py
+++ b/testing/marionette/client/marionette_driver/errors.py
@@ -36,23 +36,24 @@ class MarionetteException(Exception):
         super(MarionetteException, self).__init__(message)
 
     def __str__(self):
         msg = str(self.message)
         tb = None
 
         if self.cause:
             if type(self.cause) is tuple:
-                msg += ", caused by %r" % self.cause[0]
+                msg += ", caused by {0!r}".format(self.cause[0])
                 tb = self.cause[2]
             else:
-                msg += ", caused by %s" % self.cause
+                msg += ", caused by {}".format(self.cause)
         if self.stacktrace:
-            st = "".join(["\t%s\n" % x for x in self.stacktrace.splitlines()])
-            msg += "\nstacktrace:\n%s" % st
+            st = "".join(["\t{}\n".format(x)
+                          for x in self.stacktrace.splitlines()])
+            msg += "\nstacktrace:\n{}".format(st)
 
         if tb:
             msg += ': ' + "".join(traceback.format_tb(tb))
 
         return msg
 
 
 class ElementNotSelectableException(MarionetteException):
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -81,17 +81,17 @@ class GeckoInstance(object):
         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()
+                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
@@ -262,17 +262,17 @@ class FennecInstance(GeckoInstance):
             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:%d' % int(self.marionette_port)
+                'tcp:{}'.format(int(self.marionette_port))
             )
 
 
 class B2GDesktopInstance(GeckoInstance):
     def __init__(self, host, port, bin, **kwargs):
         # Pass a profile and change the binary to -bin so that
         # the built-in gaia profile doesn't get touched.
         if kwargs.get('profile', None) is None:
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -574,26 +574,26 @@ class Marionette(object):
         startup_timeout = startup_timeout or self.DEFAULT_STARTUP_TIMEOUT
         if self.bin:
             self.instance = self._create_instance(app, instance_args)
             self.instance.start()
             self.raise_for_port(self.wait_for_port(timeout=startup_timeout))
 
     def _create_instance(self, app, instance_args):
         if not Marionette.is_port_available(self.port, host=self.host):
-            ex_msg = "%s:%d is unavailable." % (self.host, self.port)
+            ex_msg = "{0}:{1} is unavailable.".format(self.host, self.port)
             raise errors.MarionetteException(message=ex_msg)
         if app:
             # select instance class for the given app
             try:
                 instance_class = geckoinstance.apps[app]
             except KeyError:
-                msg = 'Application "%s" unknown (should be one of %s)'
+                msg = 'Application "{0}" unknown (should be one of {1})'
                 raise NotImplementedError(
-                    msg % (app, geckoinstance.apps.keys()))
+                    msg.format(app, geckoinstance.apps.keys()))
         else:
             try:
                 if not isinstance(self.bin, basestring):
                     raise TypeError("bin must be a string if app is not specified")
                 config = ConfigParser.RawConfigParser()
                 config.read(os.path.join(os.path.dirname(self.bin),
                                          'application.ini'))
                 app = config.get('App', 'Name')
@@ -705,17 +705,17 @@ class Marionette(object):
             return list(self._unwrap_response(item) for item in value)
         else:
             return value
 
     def _handle_error(self, obj):
         if self.protocol == 1:
             if "error" not in obj or not isinstance(obj["error"], dict):
                 raise errors.MarionetteException(
-                    "Malformed packet, expected key 'error' to be a dict: %s" % obj)
+                    "Malformed packet, expected key 'error' to be a dict: {}".format(obj))
             error = obj["error"].get("status")
             message = obj["error"].get("message")
             stacktrace = obj["error"].get("stacktrace")
 
         else:
             error = obj["error"]
             message = obj["message"]
             stacktrace = obj["stacktrace"]
@@ -743,18 +743,18 @@ class Marionette(object):
         returncode = None
         name = None
         crashed = False
         if self.instance:
             if self.instance.runner.check_for_crashes(
                     test_name=self.test_name or os.path.basename(__file__)):
                 crashed = True
         if returncode is not None:
-            print ('PROCESS-CRASH | %s | abnormal termination with exit code %d' %
-                   (name, returncode))
+            print ('PROCESS-CRASH | {0} | abnormal termination with exit code {1}'
+                   .format(name, returncode))
         return crashed
 
     def force_shutdown(self):
         """Force a shutdown of the running instance.
 
         If we've launched the binary we are connected to, wait for it to shut down.
         In the case when it doesn't happen, force its shut down.
 
@@ -1007,30 +1007,30 @@ class Marionette(object):
         pref_exists = True
         self.set_context(self.CONTEXT_CHROME)
         for pref, value in prefs.iteritems():
             if type(value) is not str:
                 value = json.dumps(value)
             pref_exists = self.execute_script("""
             let prefInterface = Components.classes["@mozilla.org/preferences-service;1"]
                                           .getService(Components.interfaces.nsIPrefBranch);
-            let pref = '%s';
-            let value = '%s';
+            let pref = '{0}';
+            let value = '{1}';
             let type = prefInterface.getPrefType(pref);
-            switch(type) {
+            switch(type) {{
                 case prefInterface.PREF_STRING:
                     return value == prefInterface.getCharPref(pref).toString();
                 case prefInterface.PREF_BOOL:
                     return value == prefInterface.getBoolPref(pref).toString();
                 case prefInterface.PREF_INT:
                     return value == prefInterface.getIntPref(pref).toString();
                 case prefInterface.PREF_INVALID:
                     return false;
-            }
-            """ % (pref, value))
+            }}
+            """.format(pref, value))
             if not pref_exists:
                 break
         self.set_context(self.CONTEXT_CONTENT)
         if not pref_exists:
             self.delete_session()
             self.instance.restart(prefs)
             self.raise_for_port(self.wait_for_port())
             self.start_session()
@@ -1147,17 +1147,17 @@ class Marionette(object):
             self.instance.runner.process_handler.check_for_detached(self.session["processId"])
 
     def absolute_url(self, relative_url):
         '''
         Returns an absolute url for files served from Marionette's www directory.
 
         :param relative_url: The url of a static file, relative to Marionette's www directory.
         '''
-        return "%s%s" % (self.baseurl, relative_url)
+        return "{0}{1}".format(self.baseurl, relative_url)
 
     @do_process_check
     def start_session(self, desired_capabilities=None, session_id=None, timeout=60):
         """Create a new Marionette session.
 
         This method must be called before performing any other action.
 
         :param desired_capabilities: An optional dict of desired
@@ -1372,17 +1372,17 @@ class Marionette(object):
         :param context: Context, may be one of the class properties
             `CONTEXT_CHROME` or `CONTEXT_CONTENT`.
 
         Usage example::
 
             marionette.set_context(marionette.CONTEXT_CHROME)
         """
         if context not in [self.CONTEXT_CHROME, self.CONTEXT_CONTENT]:
-            raise ValueError("Unknown context: %s" % context)
+            raise ValueError("Unknown context: {}".format(context))
         self._send_message("setContext", {"value": context})
 
     @contextmanager
     def using_context(self, context):
         """Sets the context that Marionette commands are running in using
         a `with` statement. The state of the context on the server is
         saved before entering the block, and restored upon exiting it.
 
--- a/testing/marionette/client/marionette_driver/selection.py
+++ b/testing/marionette/client/marionette_driver/selection.py
@@ -48,20 +48,20 @@ class SelectionManager(object):
         '''Move cursor in the element by character offset.
 
         :param offset: Move the cursor to the direction by offset characters.
         :param backward: Optional, True to move backward; Default to False to
          move forward.
 
         '''
         cmd = self.js_selection_cmd() + '''
-              for (let i = 0; i < %d; ++i) {
-                  sel.modify("move", "%s", "character");
-              }
-              ''' % (offset, 'backward' if backward else 'forward')
+              for (let i = 0; i < {0}; ++i) {{
+                  sel.modify("move", "{1}", "character");
+              }}
+              '''.format(offset, 'backward' if backward else 'forward')
 
         self.element.marionette.execute_script(
             cmd, script_args=[self.element], sandbox='system')
 
     def move_cursor_to_front(self):
         '''Move cursor in the element to the front of the content.'''
         if self._input_or_textarea():
             cmd = '''arguments[0].setSelectionRange(0, 0);'''
@@ -86,17 +86,17 @@ class SelectionManager(object):
         '''Return the selection's DOMRectList object for the range at given idx.
 
         If the element is either <input> or <textarea>, return the DOMRectList of
         the range at given idx of the selection within the element. Otherwise,
         return the DOMRectList of the of the range at given idx of current selection.
 
         '''
         cmd = self.js_selection_cmd() +\
-            '''return sel.getRangeAt(%d).getClientRects();''' % idx
+            '''return sel.getRangeAt({}).getClientRects();'''.format(idx)
         return self.element.marionette.execute_script(cmd,
                                                       script_args=[self.element],
                                                       sandbox='system')
 
     def range_count(self):
         '''Get selection's range count'''
         cmd = self.js_selection_cmd() +\
             '''return sel.rangeCount;'''
--- a/testing/marionette/client/marionette_driver/transport.py
+++ b/testing/marionette/client/marionette_driver/transport.py
@@ -37,17 +37,17 @@ class Command(Message):
     TYPE = 0
 
     def __init__(self, msgid, name, params):
         Message.__init__(self, msgid)
         self.name = name
         self.params = params
 
     def __str__(self):
-        return "<Command id=%s, name=%s, params=%s>" % (self.id, self.name, self.params)
+        return "<Command id={0}, name={1}, params={2}>".format(self.id, self.name, self.params)
 
     def to_msg(self):
         msg = [Command.TYPE, self.id, self.name, self.params]
         return json.dumps(msg)
 
     @staticmethod
     def from_msg(payload):
         data = json.loads(payload)
@@ -60,17 +60,17 @@ class Response(Message):
     TYPE = 1
 
     def __init__(self, msgid, error, result):
         Message.__init__(self, msgid)
         self.error = error
         self.result = result
 
     def __str__(self):
-        return "<Response id=%s, error=%s, result=%s>" % (self.id, self.error, self.result)
+        return "<Response id={0}, error={1}, result={2}>".format(self.id, self.error, self.result)
 
     def to_msg(self):
         msg = [Response.TYPE, self.id, self.error, self.result]
         return json.dumps(msg)
 
     @staticmethod
     def from_msg(payload):
         data = json.loads(payload)
@@ -194,17 +194,17 @@ class TcpTransport(object):
 
                         return msg
 
                     else:
                         return remaining
 
                 bytes_to_recv = int(length) - len(remaining)
 
-        raise socket.timeout("Connection timed out after %ds" % self.socket_timeout)
+        raise socket.timeout("Connection timed out after {}s".format(self.socket_timeout))
 
     def connect(self):
         """Connect to the server and process the hello message we expect
         to receive in response.
 
         Returns a tuple of the protocol level and the application type.
         """
         try:
@@ -236,24 +236,24 @@ class TcpTransport(object):
             self.connect()
 
         if isinstance(obj, Message):
             data = obj.to_msg()
             if isinstance(obj, Command):
                 self.expected_response = obj
         else:
             data = json.dumps(obj)
-        payload = "%s:%s" % (len(data), data)
+        payload = "{0}:{1}".format(len(data), data)
 
         totalsent = 0
         while totalsent < len(payload):
             sent = self.sock.send(payload[totalsent:])
             if sent == 0:
-                raise IOError("Socket error after sending %d of %d bytes" %
-                              (totalsent, len(payload)))
+                raise IOError("Socket error after sending {0} of {1} bytes"
+                              .format(totalsent, len(payload)))
             else:
                 totalsent += sent
 
     def respond(self, obj):
         """Send a response to a command.  This can be an arbitrary JSON
         serialisable object or an ``Exception``.
         """
         res, err = None, None
--- a/testing/marionette/client/marionette_driver/wait.py
+++ b/testing/marionette/client/marionette_driver/wait.py
@@ -138,21 +138,21 @@ class Wait(object):
                 continue
 
             if rv is not None:
                 return rv
 
             self.clock.sleep(interval_new)
 
         if message:
-            message = " with message: %s" % message
+            message = " with message: {}".format(message)
 
         raise errors.TimeoutException(
-            "Timed out after %s seconds%s" %
-            (round((self.clock.now - start), 1), message if message else ""),
+            "Timed out after {0} seconds{1}".format(round((self.clock.now - start), 1),
+                                                    message if message else ""),
             cause=last_exc)
 
 
 def until_pred(clock, end):
     return clock.now >= end
 
 
 class SystemClock(object):
--- a/testing/marionette/harness/marionette/marionette_test/decorators.py
+++ b/testing/marionette/harness/marionette/marionette_test/decorators.py
@@ -138,32 +138,32 @@ def skip_unless_browser_pref(pref, predi
           def test_foo(self):
               pass  # test implementation here
     """
     def wrapper(target):
         @functools.wraps(target)
         def wrapped(self, *args, **kwargs):
             value = self.marionette.get_pref(pref)
             if value is None:
-                self.fail("No such browser preference: %r" % pref)
+                self.fail("No such browser preference: {0!r}".format(pref))
             if not predicate(value):
-                raise SkipTest("browser preference %r: %r" % (pref, value))
+                raise SkipTest("browser preference {0!r}: {1!r}".format((pref, value)))
             return target(self, *args, **kwargs)
         return wrapped
     return wrapper
 
 
 def skip_unless_protocol(predicate):
     """Decorator which skips a test if the predicate does not match the current protocol level."""
     def decorator(test_item):
         @functools.wraps(test_item)
         def skip_wrapper(self):
             level = self.marionette.client.protocol
             if not predicate(level):
-                raise SkipTest('skipping because protocol level is %s' % level)
+                raise SkipTest('skipping because protocol level is {}'.format(level))
             return test_item(self)
         return skip_wrapper
     return decorator
 
 
 def with_parameters(parameters):
     """Decorator which generates methods given a base method and some data.
 
--- a/testing/marionette/harness/marionette/marionette_test/testcases.py
+++ b/testing/marionette/harness/marionette/marionette_test/testcases.py
@@ -27,17 +27,17 @@ from marionette_driver.errors import (
 from mozlog import get_default_logger
 
 
 def _wraps_parameterized(func, func_suffix, args, kwargs):
     """Internal: Decorator used in class MetaParameterized."""
     def wrapper(self):
         return func(self, *args, **kwargs)
     wrapper.__name__ = func.__name__ + '_' + str(func_suffix)
-    wrapper.__doc__ = '[%s] %s' % (func_suffix, func.__doc__)
+    wrapper.__doc__ = '[{0}] {1}'.format(func_suffix, func.__doc__)
     return wrapper
 
 
 class MetaParameterized(type):
     """
     A metaclass that allow a class to use decorators.
 
     It can be used like :func:`parameterized`
@@ -48,18 +48,18 @@ class MetaParameterized(type):
 
     def __new__(cls, name, bases, attrs):
         for k, v in attrs.items():
             if callable(v) and hasattr(v, 'metaparameters'):
                 for func_suffix, args, kwargs in v.metaparameters:
                     func_suffix = cls.RE_ESCAPE_BAD_CHARS.sub('_', func_suffix)
                     wrapper = _wraps_parameterized(v, func_suffix, args, kwargs)
                     if wrapper.__name__ in attrs:
-                        raise KeyError("%s is already a defined method on %s" %
-                                       (wrapper.__name__, name))
+                        raise KeyError("{0} is already a defined method on {1}"
+                                       .format(wrapper.__name__, name))
                     attrs[wrapper.__name__] = wrapper
                 del attrs[k]
 
         return type.__new__(cls, name, bases, attrs)
 
 
 class JSTest:
     head_js_re = re.compile(r"MARIONETTE_HEAD_JS(\s*)=(\s*)['|\"](.*?)['|\"];")
@@ -228,19 +228,19 @@ class CommonTestCase(unittest.TestCase):
         """Add all the tests in the specified file to the specified suite."""
         raise NotImplementedError
 
     @property
     def test_name(self):
         if hasattr(self, 'jsFile'):
             return os.path.basename(self.jsFile)
         else:
-            return '%s.py %s.%s' % (self.__class__.__module__,
-                                    self.__class__.__name__,
-                                    self._testMethodName)
+            return '{0}.py {1}.{2}'.format(self.__class__.__module__,
+                                           self.__class__.__name__,
+                                           self._testMethodName)
 
     def id(self):
         # TBPL starring requires that the "test name" field of a failure message
         # not differ over time. The test name to be used is passed to
         # mozlog via the test id, so this is overriden to maintain
         # consistency.
         return self.test_name
 
@@ -264,17 +264,17 @@ class CommonTestCase(unittest.TestCase):
     def _deleteSession(self):
         if hasattr(self, 'start_time'):
             self.duration = time.time() - self.start_time
         if hasattr(self.marionette, 'session'):
             if self.marionette.session is not None:
                 try:
                     self.loglines.extend(self.marionette.get_logs())
                 except Exception, inst:
-                    self.loglines = [['Error getting log: %s' % inst]]
+                    self.loglines = [['Error getting log: {}'.format(inst)]]
                 try:
                     self.marionette.delete_session()
                 except (socket.error, MarionetteException, IOError):
                     # Gecko has crashed?
                     self.marionette.session = None
                     try:
                         self.marionette.client.close()
                     except socket.error:
@@ -310,17 +310,17 @@ if (!testUtils.hasOwnProperty("specialPo
         """
         marionette = marionette or self.marionette
         if not os.path.isabs(filename):
             # Find the caller's filename and make the path relative to that.
             caller_file = sys._getframe(1).f_globals.get('__file__', '')
             caller_file = os.path.abspath(caller_file)
             filename = os.path.join(os.path.dirname(caller_file), filename)
         self.assert_(os.path.exists(filename),
-                     'Script "%s" must exist' % filename)
+                     'Script "{}" must exist' .format(filename))
         original_test_name = self.marionette.test_name
         self.marionette.test_name = os.path.basename(filename)
         f = open(filename, 'r')
         js = f.read()
         args = []
 
         head_js = JSTest.head_js_re.search(js)
         if head_js:
@@ -393,17 +393,17 @@ if (!testUtils.hasOwnProperty("specialPo
                                             expected='FAIL', message=diag)
                 for failure in results['unexpectedSuccesses']:
                     diag = "" if failure.get('diag') is None else failure['diag']
                     name = ("got true, expected false" if failure.get('name') is None else
                             failure['name'])
                     self.logger.test_status(self.test_name, name, 'PASS',
                                             expected='FAIL', message=diag)
                 self.assertEqual(0, len(results['failures']),
-                                 '%d tests failed' % len(results['failures']))
+                                 '{} tests failed' .format(len(results['failures'])))
                 if len(results['unexpectedSuccesses']) > 0:
                     raise _UnexpectedSuccess('')
                 if len(results['expectedFailures']) > 0:
                     raise _ExpectedFailure((AssertionError, AssertionError(''), None))
 
             self.assertTrue(results['passed'] +
                             len(results['failures']) +
                             len(results['expectedFailures']) +
@@ -463,32 +463,33 @@ class MarionetteTestCase(CommonTestCase)
                                   methodName=testname,
                                   filepath=filepath,
                                   testvars=testvars,
                                   **kwargs))
 
     def setUp(self):
         CommonTestCase.setUp(self)
         self.marionette.test_name = self.test_name
-        self.marionette.execute_script("log('TEST-START: %s:%s')" %
-                                       (self.filepath.replace('\\', '\\\\'), self.methodName),
+        self.marionette.execute_script("log('TEST-START: {0}:{1}')"
+                                       .format(self.filepath.replace('\\', '\\\\'),
+                                               self.methodName),
                                        sandbox="simpletest")
 
     def tearDown(self):
         # In the case no session is active (eg. the application was quit), start
         # a new session for clean-up steps.
         if not self.marionette.session:
             self.marionette.start_session()
 
         if not self.marionette.check_for_crash():
             try:
                 self.marionette.clear_imported_scripts()
-                self.marionette.execute_script("log('TEST-END: %s:%s')" %
-                                               (self.filepath.replace('\\', '\\\\'),
-                                                self.methodName),
+                self.marionette.execute_script("log('TEST-END: {0}:{1}')"
+                                               .format(self.filepath.replace('\\', '\\\\'),
+                                                       self.methodName),
                                                sandbox="simpletest")
                 self.marionette.test_name = None
             except (MarionetteException, IOError):
                 # We have tried to log the test end when there is no listener
                 # object that we can access
                 pass
 
         CommonTestCase.tearDown(self)
@@ -520,23 +521,23 @@ class MarionetteJSTestCase(CommonTestCas
     def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette,
                            testvars, **kwargs):
         suite.addTest(cls(weakref.ref(marionette), jsFile=filepath, **kwargs))
 
     def runTest(self):
         if self.marionette.session is None:
             self.marionette.start_session()
         self.marionette.execute_script(
-            "log('TEST-START: %s');" % self.jsFile.replace('\\', '\\\\'),
+            "log('TEST-START: {}');".format(self.jsFile.replace('\\', '\\\\')),
             sandbox="simpletest")
 
         self.run_js_test(self.jsFile)
 
         self.marionette.execute_script(
-            "log('TEST-END: %s');" % self.jsFile.replace('\\', '\\\\'),
+            "log('TEST-END:{}s');".format(self.jsFile.replace('\\', '\\\\')),
             sandbox="simpletest")
         self.marionette.test_name = None
 
     def get_test_class_name(self):
         # returns a dot separated folders as class name
         dirname = os.path.dirname(self.jsFile).replace('\\', '/')
         if dirname.startswith('/'):
             dirname = dirname[1:]
--- a/testing/marionette/harness/marionette/runner/base.py
+++ b/testing/marionette/harness/marionette/runner/base.py
@@ -47,19 +47,19 @@ def update_mozinfo(path=None):
     return mozinfo.find_and_update_from_json(*dirs)
 
 
 class MarionetteTest(TestResult):
 
     @property
     def test_name(self):
         if self.test_class is not None:
-            return '%s.py %s.%s' % (self.test_class.split('.')[0],
-                                    self.test_class,
-                                    self.name)
+            return '{0}.py {1}.{2}'.format(self.test_class.split('.')[0],
+                                           self.test_class,
+                                           self.name)
         else:
             return self.name
 
 
 class MarionetteTestResult(StructuredTestResult, TestResultCollection):
 
     resultClass = MarionetteTest
 
@@ -181,17 +181,17 @@ class MarionetteTestResult(StructuredTes
 
     def getDescription(self, test):
         doc_first_line = test.shortDescription()
         if self.descriptions and doc_first_line:
             return '\n'.join((str(test), doc_first_line))
         else:
             desc = str(test)
             if hasattr(test, 'jsFile'):
-                desc = "%s, %s" % (test.jsFile, desc)
+                desc = "{0}, {1}".format(test.jsFile, desc)
             return desc
 
     def printLogs(self, test):
         for testcase in test._tests:
             if hasattr(testcase, 'loglines') and testcase.loglines:
                 # Don't dump loglines to the console if they only contain
                 # TEST-START and TEST-END.
                 skip_log = True
@@ -439,17 +439,17 @@ class BaseMarionetteArguments(ArgumentPa
 
         if args.this_chunk is not None and args.total_chunks is None:
             self.error('You must specify how many chunks to split the tests into.')
 
         if args.total_chunks is not None:
             if not 1 < args.total_chunks:
                 self.error('Total chunks must be greater than 1.')
             if not 1 <= args.this_chunk <= args.total_chunks:
-                self.error('Chunk to run must be between 1 and %s.' % args.total_chunks)
+                self.error('Chunk to run must be between 1 and {}.'.format(args.total_chunks))
 
         if args.jsdebugger:
             args.app_args.append('-jsdebugger')
             args.socket_timeout = None
 
         args.prefs = self._get_preferences(args.prefs_files, args.prefs_args)
 
         if args.e10s:
@@ -623,17 +623,17 @@ class BaseMarionetteTestRunner(object):
         return self._testvars
 
     def _load_testvars(self):
         data = []
         if self.testvars_paths is not None:
             for path in list(self.testvars_paths):
                 path = os.path.abspath(os.path.expanduser(path))
                 if not os.path.exists(path):
-                    raise IOError('--testvars file %s does not exist' % path)
+                    raise IOError('--testvars file {} does not exist'.format(path))
                 try:
                     with open(path) as f:
                         data.append(json.loads(f.read()))
                 except ValueError as e:
                     exc, val, tb = sys.exc_info()
                     msg = "JSON file ({0}) is not properly formatted: {1}"
                     raise exc, msg.format(os.path.abspath(path), e.message), tb
         return data
@@ -835,32 +835,31 @@ setReq.onerror = function() {
 
     def _set_baseurl(self, need_external_ip):
         # Gaia sets server_root and that means we shouldn't spin up our own httpd
         if not self.httpd:
             if self.server_root is None or os.path.isdir(self.server_root):
                 self.logger.info("starting httpd")
                 self.start_httpd(need_external_ip)
                 self.marionette.baseurl = self.httpd.get_url()
-                self.logger.info("running httpd on %s" % self.marionette.baseurl)
+                self.logger.info("running httpd on {}".format(self.marionette.baseurl))
             else:
                 self.marionette.baseurl = self.server_root
-                self.logger.info("using remote content from %s" % self.marionette.baseurl)
+                self.logger.info("using remote content from {}".format(self.marionette.baseurl))
 
     def _add_tests(self, tests):
         for test in tests:
             self.add_test(test)
 
         invalid_tests = [t['filepath'] for t in self.tests
                          if not self._is_filename_valid(t['filepath'])]
         if invalid_tests:
             raise Exception("Test file names must be of the form "
                             "'test_something.py', 'test_something.js', or 'testSomething.js'."
-                            " Invalid test names:\n  %s"
-                            % '\n  '.join(invalid_tests))
+                            " Invalid test names:\n  {}".format('\n  '.join(invalid_tests)))
 
     def _is_filename_valid(self, filename):
         filename = os.path.basename(filename)
         return self.filename_pattern.match(filename)
 
     def _log_skipped_tests(self):
         for test in self.manifest_skipped_tests:
             name = os.path.basename(test['path'])
@@ -901,17 +900,17 @@ setReq.onerror = function() {
         self._log_skipped_tests()
 
         interrupted = None
         try:
             counter = self.repeat
             while counter >= 0:
                 round_num = self.repeat - counter
                 if round_num > 0:
-                    self.logger.info('\nREPEAT %d\n-------' % round_num)
+                    self.logger.info('\nREPEAT {}\n-------'.format(round_num))
                 self.run_test_sets()
                 counter -= 1
         except KeyboardInterrupt:
             # in case of KeyboardInterrupt during the test execution
             # we want to display current test results.
             # so we keep the exception to raise it later.
             interrupted = sys.exc_info()
         except:
@@ -923,48 +922,49 @@ setReq.onerror = function() {
         try:
             self._print_summary(tests)
             self.record_crash()
             self.elapsedtime = time.time() - start_time
 
             for run_tests in self.mixin_run_tests:
                 run_tests(tests)
             if self.shuffle:
-                self.logger.info("Using seed where seed is:%d" % self.shuffle_seed)
+                self.logger.info("Using seed where seed is:{}".format(self.shuffle_seed))
 
             self.logger.info('mode: {}'.format('e10s' if self.e10s else 'non-e10s'))
             self.logger.suite_end()
         except:
             # raise only the exception if we were not interrupted
             if not interrupted:
                 raise
         finally:
             self.cleanup()
 
             # reraise previous interruption now
             if interrupted:
                 raise interrupted[0], interrupted[1], interrupted[2]
 
     def _print_summary(self, tests):
         self.logger.info('\nSUMMARY\n-------')
-        self.logger.info('passed: %d' % self.passed)
+        self.logger.info('passed: {}'.format(self.passed))
         if self.unexpected_successes == 0:
-            self.logger.info('failed: %d' % self.failed)
+            self.logger.info('failed: {}'.format(self.failed))
         else:
-            self.logger.info('failed: %d (unexpected sucesses: %d)' %
-                             (self.failed, self.unexpected_successes))
+            self.logger.info(
+                'failed: {0} (unexpected sucesses: {1})'.format(self.failed,
+                                                                self.unexpected_successes))
         if self.skipped == 0:
-            self.logger.info('todo: %d' % self.todo)
+            self.logger.info('todo: {}'.format(self.todo))
         else:
-            self.logger.info('todo: %d (skipped: %d)' % (self.todo, self.skipped))
+            self.logger.info('todo: {0} (skipped: {1})'.format(self.todo, self.skipped))
 
         if self.failed > 0:
             self.logger.info('\nFAILED TESTS\n-------')
             for failed_test in self.failures:
-                self.logger.info('%s' % failed_test[0])
+                self.logger.info('{}'.format(failed_test[0]))
 
     def start_httpd(self, need_external_ip):
         warnings.warn("start_httpd has been deprecated in favour of create_httpd",
                       DeprecationWarning)
         self.httpd = self.create_httpd(need_external_ip)
 
     def create_httpd(self, need_external_ip):
         host = "127.0.0.1"
@@ -1018,17 +1018,17 @@ setReq.onerror = function() {
             for test in manifest_tests:
                 if test.get('disabled'):
                     self.manifest_skipped_tests.append(test)
                 else:
                     target_tests.append(test)
 
             for i in target_tests:
                 if not os.path.exists(i["path"]):
-                    raise IOError("test file: %s does not exist" % i["path"])
+                    raise IOError("test file: {} does not exist".format(i["path"]))
 
                 file_ext = os.path.splitext(os.path.split(i['path'])[-1])[-1]
                 test_container = None
 
                 self.add_test(i["path"], i["expected"], test_container)
             return
 
         self.tests.append({'filepath': filepath, 'expected': expected,
@@ -1094,27 +1094,28 @@ setReq.onerror = function() {
             self.run_test(test['filepath'], test['expected'], test['test_container'])
             if self.record_crash():
                 break
 
     def run_test_sets(self):
         if len(self.tests) < 1:
             raise Exception('There are no tests to run.')
         elif self.total_chunks > len(self.tests):
-            raise ValueError('Total number of chunks must be between 1 and %d.' % len(self.tests))
+            raise ValueError('Total number of chunks must be between 1 and {}.'
+                             .format(len(self.tests)))
         if self.total_chunks > 1:
             chunks = [[] for i in range(self.total_chunks)]
             for i, test in enumerate(self.tests):
                 target_chunk = i % self.total_chunks
                 chunks[target_chunk].append(test)
 
-            self.logger.info('Running chunk %d of %d (%d tests selected from a '
-                             'total of %d)' % (self.this_chunk, self.total_chunks,
-                                               len(chunks[self.this_chunk - 1]),
-                                               len(self.tests)))
+            self.logger.info('Running chunk {0} of {1} ({2} tests selected from a '
+                             'total of {3})'.format(self.this_chunk, self.total_chunks,
+                                                    len(chunks[self.this_chunk - 1]),
+                                                    len(self.tests)))
             self.tests = chunks[self.this_chunk - 1]
 
         self.run_test_set(self.tests)
 
     def cleanup(self):
         if hasattr(self, 'httpd') and self.httpd:
             self.httpd.stop()
             self.httpd = None
--- a/testing/marionette/harness/marionette/runner/httpd.py
+++ b/testing/marionette/harness/marionette/runner/httpd.py
@@ -7,17 +7,17 @@ import time
 
 from wptserve import server, handlers, routes as default_routes
 
 
 class FixtureServer(object):
 
     def __init__(self, root, host="127.0.0.1", port=0):
         if not os.path.isdir(root):
-            raise IOError("Server root is not a valid path: %s" % root)
+            raise IOError("Server root is not a valid path: {}".format(root))
         self.root = root
         self.host = host
         self.port = port
         self._server = None
 
     def start(self, block=False):
         if self.alive:
             return
@@ -66,13 +66,13 @@ def slow_loading_document(request, respo
 <title>ok</title>
 <p>ok"""
 
 
 if __name__ == "__main__":
     here = os.path.abspath(os.path.dirname(__file__))
     doc_root = os.path.join(os.path.dirname(here), "www")
     httpd = FixtureServer(doc_root, port=2829)
-    print "Started fixture server on http://%s:%d/" % (httpd.host, httpd.port)
+    print "Started fixture server on http://{0}:{1}/".format(httpd.host, httpd.port)
     try:
         httpd.start(True)
     except KeyboardInterrupt:
         pass
--- a/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/client.py
+++ b/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/client.py
@@ -16,27 +16,27 @@ class Client(object):
         :param url: This is where the BrowserMob Proxy lives
         :param params: URL query (for example httpProxy and httpsProxy vars)
         """
         self.host = "http://" + url
         if params:
             urlparams = "?" + unquote(urlencode(params))
         else:
             urlparams = ""
-        resp = requests.post('%s/proxy' % self.host + urlparams)
+        resp = requests.post('{}/proxy'.format(self.host + urlparams))
         jcontent = json.loads(resp.content.decode('utf-8'))
         self.port = jcontent['port']
         url_parts = self.host.split(":")
         self.proxy = url_parts[1][2:] + ":" + str(self.port)
 
     def close(self):
         """
         shuts down the proxy and closes the port
         """
-        r = requests.delete('%s/proxy/%s' % (self.host, self.port))
+        r = requests.delete('{0}/proxy/{1}'.format(self.host, self.port))
         return r.status_code
 
     # webdriver integration
     # ...as a proxy object
     def selenium_proxy(self):
         """
         Returns a Selenium WebDriver Proxy class with details of the HTTP Proxy
         """
@@ -71,17 +71,17 @@ class Client(object):
         self.add_to_capabilities(capabilities)
 
     # browsermob proxy api
     @property
     def har(self):
         """
         Gets the HAR that has been recorded
         """
-        r = requests.get('%s/proxy/%s/har' % (self.host, self.port))
+        r = requests.get('{0}/proxy/{1}/har'.format(self.host, self.port))
 
         return r.json()
 
     def new_har(self, ref=None, options={}):
         """
         This sets a new HAR to be recorded
 
 
@@ -94,113 +94,113 @@ class Client(object):
         """
         if ref:
             payload = {"initialPageRef": ref}
         else:
             payload = {}
         if options:
             payload.update(options)
 
-        r = requests.put('%s/proxy/%s/har' % (self.host, self.port), payload)
+        r = requests.put('{0}/proxy/{1}/har'.format(self.host, self.port), payload)
         if r.status_code == 200:
             return (r.status_code, r.json())
         else:
             return (r.status_code, None)
 
     def new_page(self, ref=None):
         """
         This sets a new page to be recorded
 
 
         :param ref: A reference for the new page. Defaults to None
         """
         if ref:
             payload = {"pageRef": ref}
         else:
             payload = {}
-        r = requests.put('%s/proxy/%s/har/pageRef' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/har/pageRef'.format(self.host, self.port),
                          payload)
         return r.status_code
 
     def blacklist(self, regexp, status_code):
         """
         Sets a list of URL patterns to blacklist
 
 
         :param regex: a comma separated list of regular expressions
         :param status_code: the HTTP status code to return for URLs that do not \
                        match the blacklist
 
         """
-        r = requests.put('%s/proxy/%s/blacklist' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/blacklist'.format(self.host, self.port),
                          {'regex': regexp, 'status': status_code})
         return r.status_code
 
     def whitelist(self, regexp, status_code):
         """
         Sets a list of URL patterns to whitelist
 
 
         :param regex: a comma separated list of regular expressions
         :param status_code: the HTTP status code to return for URLs that do not \
                        match the whitelist
         """
-        r = requests.put('%s/proxy/%s/whitelist' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/whitelist'.format(self.host, self.port),
                          {'regex': regexp, 'status': status_code})
         return r.status_code
 
     def basic_authentication(self, domain, username, password):
         """
         This add automatic basic authentication
 
 
         :param domain: domain to set authentication credentials for
         :param username: valid username to use when authenticating
         :param  password: valid password to use when authenticating
         """
-        r = requests.post(url='%s/proxy/%s/auth/basic/%s' % (self.host, self.port, domain),
+        r = requests.post(url='{0}/proxy/{1}/auth/basic/{2}'.format(self.host, self.port, domain),
                           data=json.dumps({'username': username, 'password': password}),
                           headers={'content-type': 'application/json'})
         return r.status_code
 
     def headers(self, headers):
         """
         This sets the headers that will set by the proxy on all requests
 
 
         :param headers: this is a dictionary of the headers to be set
         """
         if not isinstance(headers, dict):
             raise TypeError("headers needs to be dictionary")
 
-        r = requests.post(url='%s/proxy/%s/headers' % (self.host, self.port),
+        r = requests.post(url='{0}/proxy/{1}/headers'.format(self.host, self.port),
                           data=json.dumps(headers),
                           headers={'content-type': 'application/json'})
         return r.status_code
 
     def response_interceptor(self, js):
         """
         Executes the javascript against each response
 
 
         :param js: the javascript to execute
         """
-        r = requests.post(url='%s/proxy/%s/interceptor/response' % (self.host, self.port),
+        r = requests.post(url='{0}/proxy/{1}/interceptor/response'.format(self.host, self.port),
                   data=js,
                   headers={'content-type': 'x-www-form-urlencoded'})
         return r.status_code
 
     def request_interceptor(self, js):
         """
         Executes the javascript against each request
 
 
         :param js: the javascript to execute
         """
-        r = requests.post(url='%s/proxy/%s/interceptor/request' % (self.host, self.port),
+        r = requests.post(url='{0}/proxy/{1}/interceptor/request'.format(self.host, self.port),
                   data=js,
                   headers={'content-type': 'x-www-form-urlencoded'})
         return r.status_code
 
     LIMITS = {
         'upstream_kbps': 'upstreamKbps',
         'downstream_kbps': 'downstreamKbps',
         'latency': 'latency'
@@ -215,24 +215,24 @@ class Client(object):
                         downstreamKbps - Sets the downstream kbps \
                         upstreamKbps - Sets the upstream kbps \
                         latency - Add the given latency to each HTTP request
         """
         params = {}
 
         for (k, v) in list(options.items()):
             if k not in self.LIMITS:
-                raise KeyError('invalid key: %s' % k)
+                raise KeyError('invalid key: {}'.format(k))
 
             params[self.LIMITS[k]] = int(v)
 
         if len(list(params.items())) == 0:
             raise KeyError("You need to specify one of the valid Keys")
 
-        r = requests.put('%s/proxy/%s/limit' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/limit'.format(self.host, self.port),
                          params)
         return r.status_code
 
     TIMEOUTS = {
         'request': 'requestTimeout',
         'read': 'readTimeout',
         'connection': 'connectionTimeout',
         'dns': 'dnsCacheTimeout'
@@ -248,79 +248,79 @@ class Client(object):
                         read - read timeout (in seconds) \
                         connection - connection timeout (in seconds) \
                         dns - dns lookup timeout (in seconds)
         """
         params = {}
 
         for (k, v) in list(options.items()):
             if k not in self.TIMEOUTS:
-                raise KeyError('invalid key: %s' % k)
+                raise KeyError('invalid key: {}'.format(k))
 
             params[self.TIMEOUTS[k]] = int(v)
 
         if len(list(params.items())) == 0:
             raise KeyError("You need to specify one of the valid Keys")
 
-        r = requests.put('%s/proxy/%s/timeout' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/timeout'.format(self.host, self.port),
                          params)
         return r.status_code
 
     def remap_hosts(self, address, ip_address):
         """
         Remap the hosts for a specific URL
 
 
         :param address: url that you wish to remap
         :param ip_address: IP Address that will handle all traffic for the address passed in
         """
         assert address is not None and ip_address is not None
-        r = requests.post('%s/proxy/%s/hosts' % (self.host, self.port),
+        r = requests.post('{0}/proxy/{1}/hosts'.format(self.host, self.port),
                          json.dumps({address: ip_address}),
                           headers={'content-type': 'application/json'})
         return r.status_code
 
     def wait_for_traffic_to_stop(self, quiet_period, timeout):
         """
         Waits for the network to be quiet
 
 
         :param quiet_period: number of miliseconds the network needs to be quiet for
         :param timeout: max number of miliseconds to wait
         """
-        r = requests.put('%s/proxy/%s/wait' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/wait'.format(self.host, self.port),
                  {'quietPeriodInMs': quiet_period, 'timeoutInMs': timeout})
         return r.status_code
 
     def clear_dns_cache(self):
         """
         Clears the DNS cache associated with the proxy instance
         """
-        r = requests.delete('%s/proxy/%s/dns/cache' % (self.host, self.port))
+        r = requests.delete('{0}/proxy/{1}/dns/cache'.format(self.host, self.port))
         return r.status_code
 
     def rewrite_url(self, match, replace):
         """
         Rewrites the requested url.
 
 
         :param match: a regex to match requests with
         :param replace: unicode \
                    a string to replace the matches with
         """
         params = {
             "matchRegex": match,
             "replace": replace
         }
-        r = requests.put('%s/proxy/%s/rewrite' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/rewrite'.format(self.host, self.port),
                          params)
         return r.status_code
 
     def retry(self, retry_count):
         """
         Retries. No idea what its used for, but its in the API...
 
 
         :param retry_count: the number of retries
         """
-        r = requests.put('%s/proxy/%s/retry' % (self.host, self.port),
+        r = requests.put('{0}/proxy/{1}/retry'.format(self.host, self.port),
                  {'retrycount': retry_count})
         return r.status_code
--- a/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/server.py
+++ b/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/server.py
@@ -27,27 +27,27 @@ class Server(object):
         exec_not_on_path = True
         for directory in os.environ['PATH'].split(path_var_sep):
             if(os.path.isfile(os.path.join(directory, path))):
                 exec_not_on_path = False
                 break
 
         if not os.path.isfile(path) and exec_not_on_path:
             raise IOError("Browsermob-Proxy binary couldn't be found in path"
-                          " provided: %s" % path)
+                          " provided: {}".format(path))
 
         self.path = path
         self.port = options.get('port', 8080)
         self.process = None
 
         if platform.system() == 'Darwin':
             self.command = ['sh']
         else:
             self.command = []
-        self.command += [path, '--port=%s' % self.port]
+        self.command += [path, '--port={}'.format(self.port)]
 
     def start(self):
         """
         This will start the browsermob proxy and then wait until it can
         interact with it
         """
         self.log_file = open(os.path.abspath('server.log'), 'w')
         self.process = subprocess.Popen(self.command,
@@ -78,17 +78,17 @@ class Server(object):
         self.log_file.close()
 
     @property
     def url(self):
         """
         Gets the url that the proxy is running on. This is not the URL clients
         should connect to.
         """
-        return "http://localhost:%d" % self.port
+        return "http://localhost:{}".format(self.port)
 
     def create_proxy(self, params={}):
         """
         Gets a client class that allow to set all the proxy details that you
         may need to.
         :param params: Dictionary where you can specify params \
                     like httpProxy and httpsProxy
         """
--- a/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/webdriver_event_listener.py
+++ b/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/browsermobproxy/webdriver_event_listener.py
@@ -1,34 +1,34 @@
 from selenium.webdriver.support.abstract_event_listener import AbstractEventListener
 
 class WebDriverEventListener(AbstractEventListener):
-    
+
     def __init__(self, client, refs={}):
         self.client = client
         self.hars = []
         self.refs = refs
 
     def before_navigate_to(self, url, driver):
         if len(self.hars) != 0:
             self.hars.append(self.client.har)
-        self.client.new_har("navigate-to-%s" % url, self.refs)
-       
+        self.client.new_har("navigate-to-{}".format(url), self.refs)
+
     def before_navigate_back(self, driver=None):
         if driver:
-            name = "-from-%s" % driver.current_url
-        else: 
+            name = "-from-{}".format(driver.current_url)
+        else:
             name = "navigate-back"
         self.client.new_page(name)
 
     def before_navigate_forward(self, driver=None):
         if driver:
-            name = "-from-%s" % driver.current_url
-        else: 
+            name = "-from-{}".format(driver.current_url)
+        else:
             name = "navigate-forward"
         self.client.new_page(name)
-                                       
+
     def before_click(self, element, driver):
-        name = "click-element-%s" % element.id
+        name = "click-element-{}".format(element.id)
         self.client.new_page(name)
-                                                                   
+
     def before_quit(self, driver):
         self.hars.append(self.client.har)
--- a/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/test/test_webdriver.py
+++ b/testing/marionette/harness/marionette/runner/mixins/browsermob-proxy-py/test/test_webdriver.py
@@ -48,13 +48,13 @@ class TestWebDriver(object):
 
         driver.quit()
 
     def test_what_things_look_like(self):
         bmp_capabilities = copy.deepcopy(selenium.webdriver.common.desired_capabilities.DesiredCapabilities.FIREFOX)
         self.client.add_to_capabilities(bmp_capabilities)
 
         proxy_capabilities = copy.deepcopy(selenium.webdriver.common.desired_capabilities.DesiredCapabilities.FIREFOX)
-        proxy_addr = 'localhost:%d' % self.client.port
+        proxy_addr = 'localhost:{}'.format(self.client.port)
         proxy = Proxy({'httpProxy': proxy_addr,'sslProxy': proxy_addr})
         proxy.add_to_capabilities(proxy_capabilities)
 
         assert bmp_capabilities == proxy_capabilities
--- a/testing/marionette/harness/marionette/runner/mixins/browsermob.py
+++ b/testing/marionette/harness/marionette/runner/mixins/browsermob.py
@@ -18,17 +18,17 @@ class BrowserMobProxyArguments(object):
          {'type': int,
           'help': 'port to run the browsermob proxy on',
           }],
     ]
 
     def verify_usage_handler(self, args):
         if args.browsermob_script is not None:
             if not os.path.exists(args.browsermob_script):
-                raise ValueError('%s not found' % args.browsermob_script)
+                raise ValueError('{} not found'.format(args.browsermob_script))
 
 
 class BrowserMobProxyTestCaseMixin(object):
 
     def __init__(self, *args, **kwargs):
         self.browsermob_server = None
         self.browsermob_port = kwargs.pop('browsermob_port')
         self.browsermob_script = kwargs.pop('browsermob_script')
@@ -46,20 +46,20 @@ class BrowserMobProxyTestCaseMixin(objec
 
     def create_browsermob_proxy(self):
         client = self.browsermob_server.create_proxy()
         with self.marionette.using_context('chrome'):
             self.marionette.execute_script("""
                 Components.utils.import("resource://gre/modules/Preferences.jsm");
                 Preferences.set("network.proxy.type", 1);
                 Preferences.set("network.proxy.http", "localhost");
-                Preferences.set("network.proxy.http_port", %(port)s);
+                Preferences.set("network.proxy.http_port", {port});
                 Preferences.set("network.proxy.ssl", "localhost");
-                Preferences.set("network.proxy.ssl_port", %(port)s);
-            """ % {"port": client.port})
+                Preferences.set("network.proxy.ssl_port", {port});
+            """.format(port=client.port))
         return client
 
     def tearDown(self):
         if self.browsermob_server:
             self.browsermob_server.stop()
             self.browsermob_server = None
 
     __del__ = tearDown
--- a/testing/marionette/harness/marionette/runner/mixins/endurance.py
+++ b/testing/marionette/harness/marionette/runner/mixins/endurance.py
@@ -68,21 +68,23 @@ class EnduranceTestCaseMixin(object):
         self.test_method = test
         self.app_under_test = app
         for function in self.drive_setup_functions:
             function(test, app)
 
         # Now drive the actual test case iterations
         for count in range(1, self.iterations + 1):
             self.iteration = count
-            self.marionette.log("%s iteration %d of %d" % (self.test_method.__name__, count, self.iterations))
+            self.marionette.log("{0} iteration {1} of {2}".format(self.test_method.__name__,
+                                                                  count,
+                                                                  self.iterations))
             # Print to console so can see what iteration we're on while test is running
             if self.iteration == 1:
                 print "\n"
-            print "Iteration %d of %d..." % (count, self.iterations)
+            print "Iteration {0} of {1}...".format(count, self.iterations)
             sys.stdout.flush()
 
             for function in self.pre_test_functions:
                 function()
 
             self.test_method()
 
             for function in self.post_test_functions:
@@ -100,23 +102,28 @@ class EnduranceTestCaseMixin(object):
         print "Checkpoint..."
         sys.stdout.flush()
         self.cur_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
         # If first checkpoint, create the file if it doesn't exist already
         if self.iteration in (0, self.checkpoint_interval):
             self.checkpoint_path = "checkpoints"
             if not os.path.exists(self.checkpoint_path):
                 os.makedirs(self.checkpoint_path, 0755)
-            self.log_name = "%s/checkpoint_%s_%s.log" % (self.checkpoint_path, self.test_method.__name__, self.cur_time)
+            self.log_name = "{0}/checkpoint_{1}_{2}.log".format(self.checkpoint_path,
+                                                                self.test_method.__name__,
+                                                                self.cur_time)
             with open(self.log_name, 'a') as log_file:
-                log_file.write('%s Endurance Test: %s\n' % (self.cur_time, self.test_method.__name__))
-                log_file.write('%s Checkpoint after iteration %d of %d:\n' % (self.cur_time, self.iteration, self.iterations))
+                log_file.write('{0} Endurance Test: {1}\n'.format(self.cur_time,
+                                                                  self.test_method.__name__))
+                log_file.write('{0} Checkpoint after iteration {1} of xs{2}%d:\n'
+                               .format(self.cur_time, self.iteration, self.iterations))
         else:
             with open(self.log_name, 'a') as log_file:
-                log_file.write('%s Checkpoint after iteration %d of %d:\n' % (self.cur_time, self.iteration, self.iterations))
+                log_file.write('{0} Checkpoint after iteration {1} of {2}:\n'
+                               .format(self.cur_time, self.iteration, self.iterations))
 
         for function in self.checkpoint_functions:
             function()
 
     def process_checkpoint_data(self):
         # Process checkpoint data into .json
         self.marionette.log("processing checkpoint data")
         for function in self.process_checkpoint_functions:
@@ -131,31 +138,32 @@ class MemoryEnduranceTestCaseMixin(objec
         self.add_process_checkpoint_function(self.memory_b2g_process_checkpoint)
 
     def memory_b2g_checkpoint(self):
         if not self.device_manager:
             return
 
         # Sleep to give device idle time (for gc)
         idle_time = 30
-        self.marionette.log("sleeping %d seconds to give the device some idle time" % idle_time)
+        self.marionette.log(
+            "sleeping {} seconds to give the device some idle time".format(idle_time))
         time.sleep(idle_time)
 
         # Dump out some memory status info
         self.marionette.log("checkpoint")
         output_str = self.device_manager.shellCheckOutput(["b2g-ps"])
         with open(self.log_name, 'a') as log_file:
-            log_file.write('%s\n' % output_str)
+            log_file.write('{}\n'.format(output_str))
 
     def memory_b2g_process_checkpoint(self):
         if not self.device_manager:
             return
 
         # Process checkpoint data into .json
-        self.marionette.log("processing checkpoint data from %s" % self.log_name)
+        self.marionette.log("processing checkpoint data from {}".format(self.log_name))
 
         # Open the checkpoint file
         checkpoint_file = open(self.log_name, 'r')
 
         # Grab every b2g rss reading for each checkpoint
         b2g_rss_list = []
         for next_line in checkpoint_file:
             if next_line.startswith("b2g"):
@@ -170,26 +178,26 @@ class MemoryEnduranceTestCaseMixin(objec
             total += int(b2g_mem_value)
         avg_rss = total / len(b2g_rss_list)
 
         # Create a summary text file
         summary_name = self.log_name.replace('.log', '_summary.log')
         summary_file = open(summary_name, 'w')
 
         # Write the summarized checkpoint data
-        summary_file.write('test_name: %s\n' % self.test_method.__name__)
-        summary_file.write('completed: %s\n' % self.cur_time)
-        summary_file.write('app_under_test: %s\n' % self.app_under_test.lower())
-        summary_file.write('total_iterations: %d\n' % self.iterations)
-        summary_file.write('checkpoint_interval: %d\n' % self.checkpoint_interval)
+        summary_file.write('test_name: {}\n'.format(self.test_method.__name__))
+        summary_file.write('completed: {}\n'.format(self.cur_time))
+        summary_file.write('app_under_test: {}\n'.format(self.app_under_test.lower()))
+        summary_file.write('total_iterations: {}\n'.format(self.iterations))
+        summary_file.write('checkpoint_interval: {}\n'.format(self.checkpoint_interval))
         summary_file.write('b2g_rss: ')
         summary_file.write(', '.join(b2g_rss_list))
-        summary_file.write('\navg_rss: %d\n\n' % avg_rss)
+        summary_file.write('\navg_rss: {}\n\n'.format(avg_rss))
 
         # Close the summary file
         summary_file.close()
 
         # Write to suite summary file
-        suite_summary_file_name = '%s/avg_b2g_rss_suite_summary.log' % self.checkpoint_path
+        suite_summary_file_name = '{}/avg_b2g_rss_suite_summary.log'.format(self.checkpoint_path)
         suite_summary_file = open(suite_summary_file_name, 'a')
-        suite_summary_file.write('%s: %s\n' % (self.test_method.__name__, avg_rss))
+        suite_summary_file.write('{0}: {1}\n'.format(self.test_method.__name__, avg_rss))
         suite_summary_file.close()
 
--- a/testing/marionette/harness/marionette/runner/mixins/reporting.py
+++ b/testing/marionette/harness/marionette/runner/mixins/reporting.py
@@ -78,29 +78,30 @@ class HTMLReportingTestRunnerMixin(objec
             result_map = {
                 'KNOWN-FAIL': 'expected failure',
                 'PASS': 'passed',
                 'UNEXPECTED-FAIL': 'failure',
                 'UNEXPECTED-PASS': 'unexpected pass'}
 
             if result.upper() in ['SKIPPED', 'UNEXPECTED-FAIL', 'KNOWN-FAIL', 'ERROR']:
                 if debug.get('screenshot'):
-                    screenshot = 'data:image/png;base64,%s' % debug['screenshot']
+                    screenshot = 'data:image/png;base64,{}'.format(debug['screenshot'])
                     additional_html.append(html.div(
                         html.a(html.img(src=screenshot), href="#"),
                         class_='screenshot'))
                 for name, content in debug.items():
                     try:
                         if 'screenshot' in name:
                             href = '#'
                         else:
                             # use base64 to avoid that some browser (such as Firefox, Opera)
                             # treats '#' as the start of another link if the data URL contains.
                             # use 'charset=utf-8' to show special characters like Chinese.
-                            href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content)
+                            href = 'data:text/plain;charset=utf-8;base64,{}'.format(
+                                base64.b64encode(content))
                         links_html.append(html.a(
                             name.title(),
                             class_=name,
                             href=href,
                             target='_blank'))
                         links_html.append(' ')
                     except:
                         pass
@@ -168,17 +169,18 @@ class HTMLReportingTestRunnerMixin(objec
                 version.get('application_changeset'),
                 href='/'.join([version.get('application_repository'),
                                version.get('application_changeset')]),
                 target='_blank')
 
         if version.get('gaia_changeset'):
             configuration['Gaia revision'] = html.a(
                 version.get('gaia_changeset')[:12],
-                href='https://github.com/mozilla-b2g/gaia/commit/%s' % version.get('gaia_changeset'),
+                href='https://github.com/mozilla-b2g/gaia/commit/{}'.format(
+                    version.get('gaia_changeset')),
                 target='_blank')
 
         doc = html.html(
             html.head(
                 html.meta(charset='utf-8'),
                 html.title('Test Report'),
                 #TODO: must redisgn this to use marionette's resourcs, instead of the caller folder's
                 html.style(raw(pkg_resources.resource_string(
@@ -186,35 +188,35 @@ class HTMLReportingTestRunnerMixin(objec
                     type='text/css')),
             html.body(
                 html.script(raw(pkg_resources.resource_string(
                     __name__, os.path.sep.join(['resources', 'htmlreport', 'jquery.js']))),
                     type='text/javascript'),
                 html.script(raw(pkg_resources.resource_string(
                     __name__, os.path.sep.join(['resources', 'htmlreport', 'main.js']))),
                     type='text/javascript'),
-                html.p('Report generated on %s at %s by %s version %s' % (
+                html.p('Report generated on {0} at {1} by {2} version {3}'.format(
                     generated.strftime('%d-%b-%Y'),
                     generated.strftime('%H:%M:%S'),
                     self.html_name, self.html_version)),
                 html.h2('Configuration'),
                 html.table(
                     [html.tr(html.td(k), html.td(v)) for k, v in sorted(configuration.items()) if v],
                     id='configuration'),
                 html.h2('Summary'),
-                html.p('%i tests ran in %i seconds.' % (tests, test_time),
+                html.p('{0} tests ran in {1} seconds.'.format(tests, test_time),
                        html.br(),
-                       html.span('%i passed' % passes, class_='passed'), ', ',
-                       html.span('%i skipped' % skips, class_='skipped'), ', ',
-                       html.span('%i failed' % failures, class_='failed'), ', ',
-                       html.span('%i errors' % errors, class_='error'), '.',
+                       html.span('{} passed'.format(passes), class_='passed'), ', ',
+                       html.span('{} skipped'.format(skips), class_='skipped'), ', ',
+                       html.span('{} failed'.format(failures), class_='failed'), ', ',
+                       html.span('{} errors'.format(errors), class_='error'), '.',
                        html.br(),
-                       html.span('%i expected failures' % expected_failures,
+                       html.span('{} expected failures'.format(expected_failures),
                                  class_='expected failure'), ', ',
-                       html.span('%i unexpected passes' % unexpected_passes,
+                       html.span('{} unexpected passes'.format(unexpected_passes),
                                  class_='unexpected pass'), '.'),
                 html.h2('Results'),
                 html.table([html.thead(
                     html.tr([
                         html.th('Result', class_='sortable', col='result'),
                         html.th('Class', class_='sortable', col='class'),
                         html.th('Test Name', class_='sortable', col='name'),
                         html.th('Duration', class_='sortable numeric', col='duration'),
--- a/testing/marionette/harness/marionette/runner/mixins/xmlgen.py
+++ b/testing/marionette/harness/marionette/runner/mixins/xmlgen.py
@@ -67,17 +67,17 @@ class Tag(list):
 
     def unicode(self, indent=2):
         l = []
         SimpleUnicodeVisitor(l.append, indent).visit(self)
         return u("").join(l)
 
     def __repr__(self):
         name = self.__class__.__name__
-        return "<%r tag object %d>" % (name, id(self))
+        return "<{0!r} tag object {1}>".format(name, id(self))
 
 Namespace = NamespaceMetaclass('Namespace', (object, ), {
     '__tagspec__': None,
     '__tagclass__': Tag,
     '__stickyname__': False,
 })
 
 class HtmlTag(Tag):
@@ -164,29 +164,29 @@ class SimpleUnicodeVisitor(object):
         except IndexError:
             tag.parent = None
         self.visited[id(tag)] = 1
         tagname = getattr(tag, 'xmlname', tag.__class__.__name__)
         if self.curindent and not self._isinline(tagname):
             self.write("\n" + u(' ') * self.curindent)
         if tag:
             self.curindent += self.indent
-            self.write(u('<%s%s>') % (tagname, self.attributes(tag)))
+            self.write(u('<{0}{1}>').format(tagname, self.attributes(tag)))
             self.parents.append(tag)
             for x in tag:
                 self.visit(x)
             self.parents.pop()
-            self.write(u('</%s>') % tagname)
+            self.write(u('</{}>').format(tagname))
             self.curindent -= self.indent
         else:
             nameattr = tagname+self.attributes(tag)
             if self._issingleton(tagname):
-                self.write(u('<%s/>') % (nameattr,))
+                self.write(u('<{}/>').format(nameattr))
             else:
-                self.write(u('<%s></%s>') % (nameattr, tagname))
+                self.write(u('<{0}></{1}>').format(nameattr, tagname))
 
     def attributes(self, tag):
         # serialize attributes
         attrlist = dir(tag.attr)
         attrlist.sort()
         l = []
         for name in attrlist:
             res = self.repr_attribute(tag.attr, name)
@@ -199,27 +199,27 @@ class SimpleUnicodeVisitor(object):
         if name[:2] != '__':
             value = getattr(attrs, name)
             if name.endswith('_'):
                 name = name[:-1]
             if isinstance(value, raw):
                 insert = value.uniobj
             else:
                 insert = escape(unicode(value))
-            return ' %s="%s"' % (name, insert)
+            return ' {0}="{1}"'.format(name, insert)
 
     def getstyle(self, tag):
         """ return attribute list suitable for styling. """
         try:
             styledict = tag.style.__dict__
         except AttributeError:
             return []
         else:
             stylelist = [x+': ' + y for x,y in styledict.items()]
-            return [u(' style="%s"') % u('; ').join(stylelist)]
+            return [u(' style="{}"').format(u('; ').join(stylelist))]
 
     def _issingleton(self, tagname):
         """can (and will) be overridden in subclasses"""
         return self.shortempty
 
     def _isinline(self, tagname):
         """can (and will) be overridden in subclasses"""
         return False
--- a/testing/marionette/harness/marionette/tests/unit/test_capabilities.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_capabilities.py
@@ -99,9 +99,10 @@ class TestCapabilities(MarionetteTestCas
             self.assertIn("CookiesAndCream does not equal", str(e))
 
         # Start a new session just to make sure we leave the browser in the
         # same state it was before it started the test
         self.marionette.start_session()
 
     def test_we_get_valid_uuid4_when_creating_a_session(self):
         self.assertNotIn("{", self.marionette.session_id,
-                         "Session ID has {} in it: %s" % self.marionette.session_id)
+                         "Session ID has {{}} in it: {}".format(
+                             self.marionette.session_id))
--- a/testing/marionette/harness/marionette/tests/unit/test_click_scrolling.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_click_scrolling.py
@@ -77,33 +77,33 @@ class TestClickScrolling(MarionetteTestC
         self.marionette.find_element(By.ID, "radio").click()
 
     def test_should_scroll_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
         test_html = self.marionette.absolute_url("element_outside_viewport.html")
 
         for s in ["top", "bottom"]:
             self.marionette.navigate(test_html)
             scroll_y = self.marionette.execute_script("return window.scrollY;")
-            self.marionette.find_element(By.ID, "%s-70" % s).click()
+            self.marionette.find_element(By.ID, "{}-70".format(s)).click()
             self.assertNotEqual(scroll_y, self.marionette.execute_script("return window.scrollY;"))
 
         for s in ["left", "right"]:
             self.marionette.navigate(test_html)
             scroll_x = self.marionette.execute_script("return window.scrollX;")
-            self.marionette.find_element(By.ID, "%s-70" % s).click()
+            self.marionette.find_element(By.ID, "{}-70".format(s)).click()
             self.assertNotEqual(scroll_x, self.marionette.execute_script("return window.scrollX;"))
 
     def test_should_not_scroll_elements_if_click_point_is_in_view(self):
         test_html = self.marionette.absolute_url("element_outside_viewport.html")
 
         for s in ["top", "right", "bottom", "left"]:
             for p in ["50", "30"]:
                 self.marionette.navigate(test_html)
                 scroll = self.marionette.execute_script("return [window.scrollX, window.scrollY];")
-                self.marionette.find_element(By.ID, "%s-%s" % (s, p)).click()
+                self.marionette.find_element(By.ID, "{0}-{1}".format(s, p)).click()
                 self.assertEqual(scroll, self.marionette.execute_script("return [window.scrollX, window.scrollY];"))
 
     @skip("Bug 1003687")
     def test_should_scroll_overflow_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
         test_html = self.marionette.absolute_url("scroll5.html")
         self.marionette.navigate(test_html)
 
         self.marionette.find_element(By.ID, "inner").click()
--- a/testing/marionette/harness/marionette/tests/unit/test_cookies.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_cookies.py
@@ -43,25 +43,25 @@ class CookieTest(MarionetteTestCase):
         self.marionette.add_cookie(self.COOKIE_A)
         cookie_returned = str(self.marionette.execute_script("return document.cookie"))
         self.assertTrue(self.COOKIE_A["name"] in cookie_returned)
         self.marionette.delete_cookie("foo")
         cookie_returned = str(self.marionette.execute_script("return document.cookie"))
         self.assertFalse(self.COOKIE_A["name"] in cookie_returned)
 
     def test_should_get_cookie_by_name(self):
-        key = "key_%d" % int(random.random()*10000000)
+        key = "key_{}".format(int(random.random()*10000000))
         self.marionette.execute_script("document.cookie = arguments[0] + '=set';", [key])
 
         cookie = self.marionette.get_cookie(key)
         self.assertEquals("set", cookie["value"])
 
     def test_get_all_cookies(self):
-        key1 = "key_%d" % int(random.random()*10000000)
-        key2 = "key_%d" % int(random.random()*10000000)
+        key1 = "key_{}".format(int(random.random()*10000000))
+        key2 = "key_{}".format(int(random.random()*10000000))
 
         cookies = self.marionette.get_cookies()
         count = len(cookies)
 
         one = {"name" :key1,
                "value": "value"}
         two = {"name":key2,
                "value": "value"}
--- a/testing/marionette/harness/marionette/tests/unit/test_element_retrieval.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_element_retrieval.py
@@ -8,30 +8,30 @@ import urllib
 from marionette import MarionetteTestCase, skip
 from marionette_driver.marionette import HTMLElement
 from marionette_driver.by import By
 from marionette_driver.errors import NoSuchElementException, InvalidSelectorException
 
 
 def inline(doc, doctype="html"):
     if doctype == "html":
-        return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+        return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
     elif doctype == "xhtml":
-        return "data:application/xhtml+xml,%s" % urllib.quote(
+        return "data:application/xhtml+xml,{}".format(urllib.quote(
 r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
     <title>XHTML might be the future</title>
   </head>
 
   <body>
-    %s
+    {}
   </body>
-</html>""" % doc)
+</html>""".format(doc)))
 
 
 id_html = inline("<p id=foo></p>", doctype="html")
 id_xhtml = inline('<p id="foo"></p>', doctype="xhtml")
 parent_child_html = inline("<div id=parent><p id=child></p></div>", doctype="html")
 parent_child_xhtml = inline('<div id="parent"><p id="child"></p></div>', doctype="xhtml")
 children_html = inline("<div><p>foo <p>bar</div>", doctype="html")
 children_xhtml = inline("<div><p>foo</p> <p>bar</p></div>", doctype="xhtml")
--- a/testing/marionette/harness/marionette/tests/unit/test_element_state.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_element_state.py
@@ -29,30 +29,30 @@ boolean_attributes = {
   "textarea": ["autofocus", "disabled", "readonly", "required"],
   "track": ["default"],
   "video": ["autoplay", "controls", "loop", "muted"],
 }
 
 
 def inline(doc, doctype="html"):
     if doctype == "html":
-        return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+        return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
     elif doctype == "xhtml":
-        return "data:application/xhtml+xml,%s" % urllib.quote(
+        return "data:application/xhtml+xml,{}".format(urllib.quote(
 r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
     <title>XHTML might be the future</title>
   </head>
 
   <body>
-    %s
+    {}
   </body>
-</html>""" % doc)
+</html>""".format(doc)))
 
 
 attribute = inline("<input foo=bar>")
 input = inline("<input>")
 disabled = inline("<input disabled=baz>")
 check = inline("<input type=checkbox>")
 
 
@@ -82,18 +82,18 @@ class TestGetElementAttribute(Marionette
         el = self.marionette.find_element(By.TAG_NAME, "p")
         attr = el.get_attribute("style")
         self.assertIsInstance(attr, types.StringTypes)
         self.assertEqual("foo", attr)
 
     def test_boolean_attributes(self):
         for tag, attrs in boolean_attributes.iteritems():
             for attr in attrs:
-                print("testing boolean attribute <%s %s>" % (tag, attr))
-                doc = inline("<%s %s>" % (tag, attr))
+                print("testing boolean attribute <{0} {1}>".format(tag, attr))
+                doc = inline("<{0} {1}>".format(tag, attr))
                 self.marionette.navigate(doc)
                 el = self.marionette.find_element(By.TAG_NAME, tag)
                 res = el.get_attribute(attr)
                 self.assertIsInstance(res, types.StringTypes)
                 self.assertEqual("true", res)
 
     def test_global_boolean_attributes(self):
         self.marionette.navigate(inline("<p hidden>foo"))
--- a/testing/marionette/harness/marionette/tests/unit/test_errors.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_errors.py
@@ -31,30 +31,30 @@ class TestErrors(marionette_test.Marione
         self.assertEquals(exc.cause, cause)
         self.assertEquals(exc.stacktrace, stacktrace)
 
     def test_str(self):
         exc = errors.MarionetteException(
             message=message, cause=cause, stacktrace=stacktrace)
         r = str(exc)
         self.assertIn(message, r)
-        self.assertIn(", caused by %r" % cause[0], r)
+        self.assertIn(", caused by {0!r}".format(cause[0]), r)
         self.assertIn("\nstacktrace:\n\tfirst\n\tsecond", r)
 
     def test_cause_string(self):
         exc = errors.MarionetteException(cause="foo")
         self.assertEqual(exc.cause, "foo")
         r = str(exc)
         self.assertIn(", caused by foo", r)
 
     def test_cause_tuple(self):
         exc = errors.MarionetteException(cause=cause)
         self.assertEqual(exc.cause, cause)
         r = str(exc)
-        self.assertIn(", caused by %r" % cause[0], r)
+        self.assertIn(", caused by {0!r}".format(cause[0]), r)
 
 
 class TestLookup(marionette_test.MarionetteTestCase):
     def test_by_known_number(self):
         self.assertEqual(errors.NoSuchElementException, errors.lookup(7))
 
     def test_by_unknown_number(self):
         self.assertEqual(errors.MarionetteException, errors.lookup(123456))
--- a/testing/marionette/harness/marionette/tests/unit/test_execute_async_script.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_execute_async_script.py
@@ -41,19 +41,19 @@ class TestExecuteAsyncContent(Marionette
         self.assertRaises(JavascriptException, self.marionette.execute_async_script, unload)
 
     def test_check_window(self):
         self.assertTrue(self.marionette.execute_async_script("marionetteScriptFinished(window !=null && window != undefined);"))
 
     def test_same_context(self):
         var1 = 'testing'
         self.assertEqual(self.marionette.execute_script("""
-            this.testvar = '%s';
+            this.testvar = '{}';
             return this.testvar;
-            """ % var1), var1)
+            """.format(var1)), var1)
         self.assertEqual(self.marionette.execute_async_script(
             "marionetteScriptFinished(this.testvar);", new_sandbox=False), var1)
 
     def test_execute_no_return(self):
         self.assertEqual(self.marionette.execute_async_script("marionetteScriptFinished()"), None)
 
     def test_execute_js_exception(self):
         try:
--- a/testing/marionette/harness/marionette/tests/unit/test_execute_isolate.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_execute_isolate.py
@@ -13,23 +13,23 @@ class TestExecuteIsolationContent(Marion
 
     def test_execute_async_isolate(self):
         # Results from one execute call that has timed out should not
         # contaminate a future call.
         multiplier = "*3" if self.content else "*1"
         self.marionette.set_script_timeout(500)
         self.assertRaises(ScriptTimeoutException,
                           self.marionette.execute_async_script,
-                          ("setTimeout(function() { marionetteScriptFinished(5%s); }, 3000);"
-                               % multiplier))
+                          ("setTimeout(function() {{ marionetteScriptFinished(5{}); }}, 3000);"
+                              .format(multiplier)))
 
         self.marionette.set_script_timeout(6000)
         result = self.marionette.execute_async_script("""
-setTimeout(function() { marionetteScriptFinished(10%s); }, 5000);
-""" % multiplier)
+        setTimeout(function() {{ marionetteScriptFinished(10{}); }}, 5000);
+        """.format(multiplier))
         self.assertEqual(result, 30 if self.content else 10)
 
 class TestExecuteIsolationChrome(TestExecuteIsolationContent):
     def setUp(self):
         super(TestExecuteIsolationChrome, self).setUp()
         self.marionette.set_context("chrome")
         self.content = False
 
--- a/testing/marionette/harness/marionette/tests/unit/test_execute_script.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_execute_script.py
@@ -6,17 +6,17 @@ import urllib
 import os
 
 from marionette_driver import By, errors
 from marionette_driver.marionette import HTMLElement
 from marionette import MarionetteTestCase
 
 
 def inline(doc):
-    return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+    return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
 
 elements = inline("<p>foo</p> <p>bar</p>")
 
 globals = set([
               "atob",
               "Audio",
               "btoa",
@@ -105,19 +105,19 @@ class TestExecuteContent(MarionetteTestC
             [1, 2], self.marionette.execute_script("return arguments[0]", [[1, 2]]))
 
     def test_argument_object(self):
         self.assertEqual({"foo": 1}, self.marionette.execute_script(
             "return arguments[0]", [{"foo": 1}]))
 
     def assert_is_defined(self, property, sandbox="default"):
         self.assertTrue(self.marionette.execute_script(
-            "return typeof %s != 'undefined'" % property,
+            "return typeof {} != 'undefined'".format(property),
             sandbox=sandbox),
-            "property %s is undefined" % property)
+                        "property {} is undefined".format(property))
 
     def test_globals(self):
         for property in globals:
             self.assert_is_defined(property)
         self.assert_is_defined("Components")
         self.assert_is_defined("window.wrappedJSObject")
 
     def test_system_globals(self):
@@ -221,18 +221,18 @@ class TestExecuteContent(MarionetteTestC
             return self.marionette._send_message(
                 "executeScript", {"script": script}, key="value")
 
         send("window.foo = 1")
         foo = send("return window.foo")
         self.assertEqual(1, foo)
 
         for property in globals:
-            exists = send("return typeof %s != 'undefined'" % property)
-            self.assertTrue(exists, "property %s is undefined" % property)
+            exists = send("return typeof {} != 'undefined'".format(property))
+            self.assertTrue(exists, "property {} is undefined".format(property))
         # TODO(ato): For some reason this fails, probably Sandbox bug?
         # self.assertTrue(send("return typeof Components == 'undefined'"))
         self.assertTrue(
             send("return typeof window.wrappedJSObject == 'undefined'"))
 
     def test_no_callback(self):
         self.assertTrue(self.marionette.execute_script(
             "return typeof arguments[0] == 'undefined'"))
--- a/testing/marionette/harness/marionette/tests/unit/test_expected.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_expected.py
@@ -6,23 +6,23 @@ import urllib
 
 from marionette_driver import expected
 from marionette_driver.by import By
 
 from marionette import marionette_test
 
 
 def inline(doc):
-    return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+    return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
 static_element = inline("""<p>foo</p>""")
 static_elements = static_element + static_element
 
 remove_element_by_tag_name = \
-    """var el = document.getElementsByTagName('%s')[0];
+    """var el = document.getElementsByTagName('{}')[0];
     document.getElementsByTagName("body")[0].remove(el);"""
 
 hidden_element = inline("<p style='display: none'>hidden</p>")
 
 selected_element = inline("<option selected>selected</option>")
 unselected_element = inline("<option>unselected</option>")
 
 enabled_element = inline("<input>")
@@ -71,17 +71,17 @@ class TestExpected(marionette_test.Mario
         r = expected.element_not_present(p)(self.marionette)
         self.assertIsInstance(r, bool)
         self.assertFalse(r)
 
     def test_element_stale(self):
         self.marionette.navigate(static_element)
         el = self.marionette.find_element(By.TAG_NAME, "p")
         self.assertIsNotNone(el)
-        self.marionette.execute_script(remove_element_by_tag_name % "p")
+        self.marionette.execute_script(remove_element_by_tag_name.format("p"))
         r = expected.element_stale(el)(self.marionette)
         self.assertTrue(r)
 
     def test_element_stale_is_not_stale(self):
         self.marionette.navigate(static_element)
         el = self.marionette.find_element(By.TAG_NAME, "p")
         r = expected.element_stale(el)(self.marionette)
         self.assertFalse(r)
--- a/testing/marionette/harness/marionette/tests/unit/test_file_upload.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_file_upload.py
@@ -7,23 +7,23 @@ import urllib
 
 from tempfile import NamedTemporaryFile as tempfile
 
 from marionette import MarionetteTestCase, skip
 from marionette_driver import By, errors, expected
 from marionette_driver.wait import Wait
 
 
-single = "data:text/html,%s" % urllib.quote("<input type=file>")
-multiple = "data:text/html,%s" % urllib.quote("<input type=file multiple>")
-upload = lambda url: "data:text/html,%s" % urllib.quote("""
-    <form action='%s' method=post enctype='multipart/form-data'>
+single = "data:text/html,{}".format(urllib.quote("<input type=file>"))
+multiple = "data:text/html,{}".format(urllib.quote("<input type=file multiple>"))
+upload = lambda url: "data:text/html,{}".format(urllib.quote("""
+    <form action='{}' method=post enctype='multipart/form-data'>
      <input type=file>
      <input type=submit>
-    </form>""" % url)
+    </form>""".format(url)))
 
 
 class TestFileUpload(MarionetteTestCase):
     def test_sets_one_file(self):
         self.marionette.navigate(single)
         input = self.input
 
         exp = None
--- a/testing/marionette/harness/marionette/tests/unit/test_gesture.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_gesture.py
@@ -17,20 +17,20 @@ class testGestures(MarionetteTestCase):
                  rect.right <= (window.pageXOffset + window.innerWidth)
          );   
         };
     """
     def test_smooth_scroll(self):
         testAction = self.marionette.absolute_url("testAction.html")
         self.marionette.navigate(testAction)
         button = self.marionette.find_element(By.ID, "button2")
-        self.assertFalse(self.marionette.execute_script("%s; return elementInViewport(document.getElementById('buttonScroll'));" % self.check_in_viewport))
+        self.assertFalse(self.marionette.execute_script("{}; return elementInViewport(document.getElementById('buttonScroll'));" .format(elf.check_in_viewport)))
         smooth_scroll(self.marionette, button, "y",  -1, 800)
         buttonScroll = self.marionette.find_element(By.ID, "buttonScroll")
-        self.wait_for_condition(lambda m: m.execute_script("%s; return elementInViewport(arguments[0]);" % self.check_in_viewport, [buttonScroll]) == True)
+        self.wait_for_condition(lambda m: m.execute_script("{}; return elementInViewport(arguments[0]);".format(self.check_in_viewport, [buttonScroll]) == True))
         self.assertEqual("button2-touchstart", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
 
     """
     #This test doesn't manipulate the page, filed Bug 870377 about it.
     def test_pinch(self):
         testAction = self.marionette.absolute_url("testAction.html")
         self.marionette.navigate(testAction)
         button = self.marionette.find_element(By.ID, "button1")
--- a/testing/marionette/harness/marionette/tests/unit/test_getactiveframe_oop.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_getactiveframe_oop.py
@@ -38,19 +38,19 @@ class TestGetActiveFrameOOP(MarionetteTe
         # Create first OOP frame
         self.marionette.execute_script("""
             let iframe1 = document.createElement("iframe");
             iframe1.id = "remote_iframe1";
             iframe1.setAttribute('remote', true);
             iframe1.setAttribute('mozbrowser', true);
             iframe1.style.height = "100px";
             iframe1.style.width = "100%%";
-            iframe1.src = "%s";
+            iframe1.src = "{}";
             document.body.appendChild(iframe1);
-            """ % self.marionette.absolute_url("test_oop_1.html"))
+            """.format(self.marionette.absolute_url("test_oop_1.html")))
 
         # Currently no active frame
         self.assertEqual(self.marionette.get_active_frame(), None)
         self.assertTrue("test.html" in self.marionette.get_url())
 
         # Switch to iframe1, get active frame
         frame = self.marionette.find_element(By.ID, 'remote_iframe1')
         self.marionette.switch_to_frame(frame)
@@ -66,19 +66,19 @@ class TestGetActiveFrameOOP(MarionetteTe
         self.marionette.switch_to_frame()
         self.marionette.execute_script("""
             let iframe2 = document.createElement("iframe");
             iframe2.setAttribute('mozbrowser', true);
             iframe2.setAttribute('remote', true);
             iframe2.id = "remote_iframe2";
             iframe2.style.height = "100px";
             iframe2.style.width = "100%%";
-            iframe2.src = "%s";
+            iframe2.src = "{}";
             document.body.appendChild(iframe2);
-            """ % self.marionette.absolute_url("test_oop_2.html"))
+            """.format(self.marionette.absolute_url("test_oop_2.html")))
 
         # Switch to iframe2, get active frame
         frame2 = self.marionette.find_element(By.ID, 'remote_iframe2')
         self.marionette.switch_to_frame(frame2)
         active_frame2 = self.marionette.get_active_frame()
         self.assertNotEqual(active_frame2.id, None)
 
         # Switch to top-level then back to active frame 1, verify correct frame
--- a/testing/marionette/harness/marionette/tests/unit/test_import_script.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_import_script.py
@@ -32,26 +32,26 @@ class TestImportScriptContent(Marionette
         return self.marionette._send_message("getContext", key="value")
 
     @property
     def other_context(self):
         return self.contexts.copy().difference([self.current_context]).pop()
 
     def is_defined(self, symbol):
         return self.marionette.execute_script(
-            "return typeof %s != 'undefined'" % symbol)
+            "return typeof {} != 'undefined'".format(symbol))
 
     def assert_defined(self, symbol, msg=None):
         if msg is None:
-            msg = "Expected symbol %s to be defined" % symbol
+            msg = "Expected symbol {} to be defined".format(symbol)
         self.assertTrue(self.is_defined(symbol), msg)
 
     def assert_undefined(self, symbol, msg=None):
         if msg is None:
-            msg = "Expected symbol %s to be undefined" % symbol
+            msg = "Expected symbol {} to be undefined".format(symbol)
         self.assertFalse(self.is_defined(symbol), msg)
 
     def assert_scripts_cleared(self):
         self.marionette.import_script(self.script_file)
         self.assert_defined("testFunc")
         self.marionette.clear_imported_scripts()
         self.assert_undefined("testFunc")
 
@@ -105,23 +105,23 @@ class TestImportScriptContent(Marionette
     @skip_if_chrome
     def test_imports_apply_globally(self):
         self.marionette.navigate(
             self.marionette.absolute_url("test_windows.html"))
         original_window = self.marionette.current_window_handle
         self.marionette.find_element(By.LINK_TEXT, "Open new window").click()
 
         windows = set(self.marionette.window_handles)
-        print "windows=%s" % windows
+        print "windows={}".format(windows)
         new_window = windows.difference([original_window]).pop()
         self.marionette.switch_to_window(new_window)
 
         self.marionette.import_script(self.script_file)
         self.marionette.close()
 
-        print "switching to original window: %s" % original_window
+        print "switching to original window: {}".format(original_window)
         self.marionette.switch_to_window(original_window)
         self.assert_defined("testFunc")
 
 
 class TestImportScriptChrome(TestImportScriptContent):
     def reset_context(self):
         self.marionette.set_context("chrome")
--- a/testing/marionette/harness/marionette/tests/unit/test_proxy.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_proxy.py
@@ -201,17 +201,17 @@ class TestProxy(MarionetteTestCase):
                 "sslProxyPort": Services.prefs.getIntPref('network.proxy.ssl_port'),
                 "ftpProxy": Services.prefs.getCharPref('network.proxy.ftp'),
                 "ftpProxyPort": Services.prefs.getIntPref('network.proxy.ftp_port'),
                 }
             """)
 
         self.assertEqual(result["proxyType"], 1)
         self.assertNotEqual(result["httpProxy"], url,
-                            'httpProxy was set. %s' % result["httpProxy"])
+                            'httpProxy was set. {}'.format(result["httpProxy"]))
         self.assertNotEqual(result["httpProxyPort"], port, 'httpProxyPort was set')
         self.assertNotEqual(result["sslProxy"], url, 'sslProxy url was set')
         self.assertNotEqual(result["sslProxyPort"], port, 'sslProxyPort was set')
         self.assertEqual(result["ftpProxy"], url, 'ftpProxy was set')
         self.assertEqual(result["ftpProxyPort"], port, 'ftpProxyPort was set')
 
 
 
--- a/testing/marionette/harness/marionette/tests/unit/test_screen_orientation.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_screen_orientation.py
@@ -2,17 +2,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from marionette_driver import errors
 from marionette import MarionetteTestCase, skip_if_desktop, skip_if_mobile
 from mozrunner.devices.emulator_screen import EmulatorScreen
 
 default_orientation = "portrait-primary"
-unknown_orientation = "Unknown screen orientation: %s"
+unknown_orientation = "Unknown screen orientation: {}"
 
 class TestScreenOrientation(MarionetteTestCase):
     def setUp(self):
         MarionetteTestCase.setUp(self)
         self.is_mobile = self.marionette.session_capabilities.get("rotatable", False)
 
     def tearDown(self):
         if self.is_mobile:
@@ -64,20 +64,20 @@ class TestScreenOrientation(MarionetteTe
     @skip_if_desktop
     def test_set_orientation_with_mixed_casing(self):
         self.marionette.set_orientation("lAnDsCaPe")
         new_orientation = self.marionette.orientation
         self.assertEqual(new_orientation, "landscape-primary")
 
     @skip_if_desktop
     def test_set_invalid_orientation(self):
-        with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation % "cheese"):
+        with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")):
             self.marionette.set_orientation("cheese")
 
     @skip_if_desktop
     def test_set_null_orientation(self):
-        with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation % "null"):
+        with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")):
             self.marionette.set_orientation(None)
 
     @skip_if_mobile
     def test_unsupported_operation_on_desktop(self):
         with self.assertRaises(errors.UnsupportedOperationException):
             self.marionette.set_orientation("landscape-primary")
--- a/testing/marionette/harness/marionette/tests/unit/test_screenshot.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_screenshot.py
@@ -11,17 +11,17 @@ import urllib
 
 from unittest import skip
 
 from marionette import MarionetteTestCase
 from marionette_driver.by import By
 
 
 def inline(doc, mime="text/html;charset=utf-8"):
-    return "data:%s,%s" % (mime, urllib.quote(doc))
+    return "data:{0},{1}".format(mime, urllib.quote(doc))
 
 
 ELEMENT = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVklEQVRoge3PMQ0AMAzAsPJHVWYbjEWTj/zx7O75oXk9AAISD6QWSC2QWiC1QGqB1AKpBVILpBZILZBaILVAaoHUAqkFUgukFkgtkFogtUBqgdT6BnIBMKa1DtYxhPkAAAAASUVORK5CYII="
 HIGHLIGHTED_ELEMENT = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVklEQVRoge3PQRHAQAgAMfyrwhm1sb3JIwIyN3MvmJu53f01kRqRGpEakRqRGpEakRqRGpEakRqRGpEakRqRGpEakRqRGpEakRqRGpEakRqRmvciL/gAQgW/OxTpMPwAAAAASUVORK5CYII="
 
 
 box = inline(
     "<div id=green style='width: 50px; height: 50px; background: silver;'></div>")
--- a/testing/marionette/harness/marionette/tests/unit/test_select.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_select.py
@@ -4,17 +4,17 @@
 
 import urllib
 
 from marionette import MarionetteTestCase
 from marionette_driver.by import By
 
 
 def inline(doc):
-    return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+    return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
 
 class SelectTestCase(MarionetteTestCase):
     def assertSelected(self, option_element):
         self.assertTrue(option_element.is_selected(), "<option> element not selected")
         self.assertTrue(self.marionette.execute_script(
             "return arguments[0].selected", script_args=[option_element], sandbox=None),
             "<option> selected attribute not updated")
--- a/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py
@@ -34,30 +34,30 @@ class TestSetWindowSize(MarionetteTestCa
 
         # valid size
         width = self.max_width - 100
         height = self.max_height - 100
         self.marionette.set_window_size(width, height)
         self.wait_for_condition(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event;"))
         size = self.marionette.window_size
         self.assertEqual(size['width'], width,
-                         "Window width is %s but should be %s" % (size['width'], width))
+                         "Window width is {0} but should be {1}".format(size['width'], width))
         self.assertEqual(size['height'], height,
-                         "Window height is %s but should be %s" % (size['height'], height))
+                         "Window height is {0} but should be {1}".format(size['height'], height))
 
     def test_that_we_can_get_new_size_when_set_window_size(self):
         actual = self.marionette.window_size
         width = actual['width'] - 50
         height = actual['height'] - 50
         size = self.marionette.set_window_size(width, height)
         self.assertIsNotNone(size, "Response is None")
         self.assertEqual(size['width'], width,
-                         "New width is %s but should be %s" % (size['width'], width))
+                         "New width is {0} but should be {1}".format(size['width'], width))
         self.assertEqual(size['height'], height,
-                         "New height is %s but should be %s" % (size['height'], height))
+                         "New height is {0} but should be {1}".format(size['height'], height))
 
     def test_possible_to_request_window_larger_than_screen(self):
         self.marionette.set_window_size(4 * self.max_width, 4 * self.max_height)
         size = self.marionette.window_size
 
         # In X the window size may be greater than the bounds of the screen
         self.assertGreaterEqual(size["width"], self.max_width)
         self.assertGreaterEqual(size["height"], self.max_height)
--- a/testing/marionette/harness/marionette/tests/unit/test_switch_remote_frame.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_switch_remote_frame.py
@@ -51,38 +51,38 @@ class TestSwitchRemoteFrame(MarionetteTe
         self.marionette.push_permission('browser', True)
         self.marionette.execute_script("""
             let iframe = document.createElement("iframe");
             iframe.setAttribute('mozbrowser', true);
             iframe.setAttribute('remote', true);
             iframe.id = "remote_iframe";
             iframe.style.height = "100px";
             iframe.style.width = "100%%";
-            iframe.src = "%s";
+            iframe.src = "{}";
             document.body.appendChild(iframe);
-            """ % self.marionette.absolute_url("test.html"))
+            """.format(self.marionette.absolute_url("test.html")))
         remote_iframe = self.marionette.find_element(By.ID, "remote_iframe")
         self.marionette.switch_to_frame(remote_iframe)
         main_process = self.is_main_process
         self.assertFalse(main_process)
 
     def test_remote_frame_revisit(self):
         # test if we can revisit a remote frame (this takes a different codepath)
         self.marionette.navigate(self.marionette.absolute_url("test.html"))
         self.marionette.push_permission('browser', True)
         self.marionette.execute_script("""
             let iframe = document.createElement("iframe");
             iframe.setAttribute('mozbrowser', true);
             iframe.setAttribute('remote', true);
             iframe.id = "remote_iframe";
             iframe.style.height = "100px";
             iframe.style.width = "100%%";
-            iframe.src = "%s";
+            iframe.src = "{}";
             document.body.appendChild(iframe);
-            """ % self.marionette.absolute_url("test.html"))
+            """.format(self.marionette.absolute_url("test.html")))
         self.marionette.switch_to_frame(self.marionette.find_element(By.ID,
                                                                      "remote_iframe"))
         main_process = self.is_main_process
         self.assertFalse(main_process)
         self.marionette.switch_to_frame()
         main_process = self.is_main_process
         should_be_main_process = not self.multi_process_browser
         self.assertEqual(main_process, should_be_main_process)
@@ -97,19 +97,19 @@ class TestSwitchRemoteFrame(MarionetteTe
         self.marionette.push_permission('browser', True)
         self.marionette.execute_script("""
             let iframe = document.createElement("iframe");
             iframe.setAttribute('mozbrowser', true);
             iframe.setAttribute('remote', true);
             iframe.id = "remote_iframe";
             iframe.style.height = "100px";
             iframe.style.width = "100%%";
-            iframe.src = "%s";
+            iframe.src = "{}";
             document.body.appendChild(iframe);
-            """ % self.marionette.absolute_url("test.html"))
+            """.format(self.marionette.absolute_url("test.html")))
         self.marionette.switch_to_frame(0)
         main_process = self.is_main_process
         self.assertFalse(main_process)
         self.marionette.switch_to_frame()
         main_process = self.is_main_process
         should_be_main_process = not self.multi_process_browser
         self.assertEqual(main_process, should_be_main_process)
         self.marionette.switch_to_frame(0)
--- a/testing/marionette/harness/marionette/tests/unit/test_transport.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_transport.py
@@ -42,17 +42,17 @@ class TestMessageSequencing(MarionetteTe
         before = self.last_id
         self.send(*get_current_url)
         self.assertGreater(self.last_id, before)
 
 
 class MessageTestCase(MarionetteTestCase):
     def assert_attr(self, obj, attr):
         self.assertTrue(hasattr(obj, attr),
-                        "object does not have attribute %s" % attr)
+                        "object does not have attribute {}".format(attr))
 
 
 class TestCommand(MessageTestCase):
     def create(self, msgid="msgid", name="name", params="params"):
         return Command(msgid, name, params)
 
     def test_initialise(self):
         cmd = self.create()
--- a/testing/marionette/harness/marionette/tests/unit/test_typing.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_typing.py
@@ -6,17 +6,17 @@ import urllib
 
 from marionette import MarionetteTestCase
 from marionette_driver.keys import Keys
 from marionette_driver.errors import ElementNotVisibleException
 from marionette_driver.by import By
 
 
 def inline(doc):
-    return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+    return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
 
 class TestTyping(MarionetteTestCase):
     def testShouldFireKeyPressEvents(self):
         test_html = self.marionette.absolute_url("javascriptPage.html")
         self.marionette.navigate(test_html)
         keyReporter = self.marionette.find_element(By.ID, "keyReporter")
         keyReporter.send_keys("a")
--- a/testing/marionette/harness/marionette/tests/unit/test_wait.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_wait.py
@@ -213,17 +213,17 @@ class WaitUntilTest(MarionetteTestCase):
         try:
             self.wt.until(lambda x: x.exception(e=TypeError))
         except Exception as e:
             exc = e
 
         s = str(exc)
         self.assertIsNotNone(exc)
         self.assertIsInstance(exc, errors.TimeoutException)
-        self.assertIn(", caused by %r" % TypeError, s)
+        self.assertIn(", caused by {0!r}".format(TypeError), s)
         self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s)
 
     def test_ignored_exception_after_timeout_is_not_raised(self):
         with self.assertRaises(errors.TimeoutException):
             r = self.wt.until(lambda x: x.exception(wait=15))
         self.assertEqual(self.clock.ticks, 10)
 
     def test_keyboard_interrupt(self):
--- a/testing/marionette/harness/session/runner/base.py
+++ b/testing/marionette/harness/session/runner/base.py
@@ -32,17 +32,17 @@ from marionette.runner import httpd
 here = os.path.abspath(os.path.dirname(__file__))
 
 
 class SessionTest(TestResult):
 
     @property
     def test_name(self):
         if self.test_class is not None:
-            return '%s.py %s.%s' % (self.test_class.split('.')[0],
+            return '{0}.py {1}.{2}'.format(self.test_class.split('.')[0],
                                     self.test_class,
                                     self.name)
         else:
             return self.name
 
 class SessionTestResult(StructuredTestResult, TestResultCollection):
 
     resultClass = SessionTest
@@ -161,17 +161,17 @@ class SessionTestResult(StructuredTestRe
 
     def getDescription(self, test):
         doc_first_line = test.shortDescription()
         if self.descriptions and doc_first_line:
             return '\n'.join((str(test), doc_first_line))
         else:
             desc = str(test)
             if hasattr(test, 'jsFile'):
-                desc = "%s, %s" % (test.jsFile, desc)
+                desc = "{0}, {1}".format(test.jsFile, desc)
             return desc
 
     def printLogs(self, test):
         for testcase in test._tests:
             if hasattr(testcase, 'loglines') and testcase.loglines:
                 # Don't dump loglines to the console if they only contain
                 # TEST-START and TEST-END.
                 skip_log = True
@@ -390,17 +390,17 @@ class BaseSessionArguments(ArgumentParse
 
         if args.this_chunk is not None and args.total_chunks is None:
             self.error('You must specify how many chunks to split the tests into.')
 
         if args.total_chunks is not None:
             if not 1 <= args.total_chunks:
                 self.error('Total chunks must be greater than 1.')
             if not 1 <= args.this_chunk <= args.total_chunks:
-                self.error('Chunk to run must be between 1 and %s.' % args.total_chunks)
+                self.error('Chunk to run must be between 1 and {}.'.format(args.total_chunks))
 
         if args.jsdebugger:
             args.app_args.append('-jsdebugger')
             args.socket_timeout = None
 
         args.prefs = self._get_preferences(args.prefs_files, args.prefs_args)
 
         if args.e10s:
@@ -530,23 +530,23 @@ class BaseSessionTestRunner(object):
         return self._testvars
 
     def _load_testvars(self):
         data = []
         if self.testvars_paths is not None:
             for path in list(self.testvars_paths):
                 path = os.path.abspath(os.path.expanduser(path))
                 if not os.path.exists(path):
-                    raise IOError('--testvars file %s does not exist' % path)
+                    raise IOError('--testvars file {} does not exist'.format(path))
                 try:
                     with open(path) as f:
                         data.append(json.loads(f.read()))
                 except ValueError as e:
-                    raise Exception("JSON file (%s) is not properly "
-                                    "formatted: %s" % (os.path.abspath(path),
+                    raise Exception("JSON file ({0}) is not properly "
+                                    "formatted: {1}".format(os.path.abspath(path),
                                                        e.message))
         return data
 
     @property
     def bin(self):
         return self._bin
 
     @bin.setter
@@ -575,34 +575,34 @@ class BaseSessionTestRunner(object):
         self.start_time = time.time()
 
         # Gaia sets server_root and that means we shouldn't spin up our own httpd
         if not self.httpd:
             if self.server_root is None or os.path.isdir(self.server_root):
                 self.logger.info("starting httpd")
                 self.httpd = self.create_httpd(False)
                 self.base_url = self.httpd.get_url()
-                self.logger.info("running httpd on %s" % self.base_url)
+                self.logger.info("running httpd on {}".format(self.base_url))
             else:
                 self.base_url = self.server_root
-                self.logger.info("using remote content from %s" % self.base_url)
+                self.logger.info("using remote content from {}".format(self.base_url))
 
         device_info = None
 
         for test in tests:
             self.add_test(test)
 
         # ensure we have only tests files with names starting with 'test_'
         invalid_tests = \
             [t['filepath'] for t in self.tests
              if not os.path.basename(t['filepath']).startswith('test_')]
         if invalid_tests:
             raise Exception("Tests file names must starts with 'test_'."
-                            " Invalid test names:\n  %s"
-                            % '\n  '.join(invalid_tests))
+                            " Invalid test names:\n  {}".format(
+                                '\n  '.join(invalid_tests)))
 
         self.logger.info("running with e10s: {}".format(self.e10s))
 
         self.logger.suite_start(self.tests)
 
         for test in self.manifest_skipped_tests:
             name = os.path.basename(test['path'])
             self.logger.test_start(name)
@@ -612,17 +612,17 @@ class BaseSessionTestRunner(object):
             self.todo += 1
 
         interrupted = None
         try:
             counter = self.repeat
             while counter >=0:
                 round = self.repeat - counter
                 if round > 0:
-                    self.logger.info('\nREPEAT %d\n-------' % round)
+                    self.logger.info('\nREPEAT {}\n-------'.format(round))
                 self.run_test_sets()
                 counter -= 1
         except KeyboardInterrupt:
             # in case of KeyboardInterrupt during the test execution
             # we want to display current test results.
             # so we keep the exception to raise it later.
             interrupted = sys.exc_info()
         try:
@@ -633,38 +633,40 @@ class BaseSessionTestRunner(object):
                 raise
         finally:
             # reraise previous interruption now
             if interrupted:
                 raise interrupted[0], interrupted[1], interrupted[2]
 
     def _print_summary(self, tests):
         self.logger.info('\nSUMMARY\n-------')
-        self.logger.info('passed: %d' % self.passed)
+        self.logger.info('passed: {}'.format(self.passed))
         if self.unexpected_successes == 0:
-            self.logger.info('failed: %d' % self.failed)
+            self.logger.info('failed: {}'.format(self.failed))
         else:
-            self.logger.info('failed: %d (unexpected sucesses: %d)' % (self.failed, self.unexpected_successes))
+            self.logger.info('failed: {0} '
+                             '(unexpected sucesses: {1})'.format(self.failed,
+                                                                 self.unexpected_successes))
         if self.skipped == 0:
-            self.logger.info('todo: %d' % self.todo)
+            self.logger.info('todo: {}'.format(self.todo))
         else:
-            self.logger.info('todo: %d (skipped: %d)' % (self.todo, self.skipped))
+            self.logger.info('todo: {0} (skipped: {1})'.format(self.todo, self.skipped))
 
         if self.failed > 0:
             self.logger.info('\nFAILED TESTS\n-------')
             for failed_test in self.failures:
-                self.logger.info('%s' % failed_test[0])
+                self.logger.info(str(failed_test[0]))
 
         self.end_time = time.time()
         self.elapsedtime = self.end_time - self.start_time
 
         for run_tests in self.mixin_run_tests:
             run_tests(tests)
         if self.shuffle:
-            self.logger.info("Using seed where seed is:%d" % self.shuffle_seed)
+            self.logger.info("Using seed where seed is: {}".format(self.shuffle_seed))
 
         self.logger.info('mode: {}'.format('e10s' if self.e10s else 'non-e10s'))
         self.logger.suite_end()
 
     def create_httpd(self, need_external_ip):
         host = "127.0.0.1"
         if need_external_ip:
             host = moznetwork.get_ip()
@@ -708,17 +710,17 @@ class BaseSessionTestRunner(object):
             for test in manifest_tests:
                 if test.get('disabled'):
                     self.manifest_skipped_tests.append(test)
                 else:
                     target_tests.append(test)
 
             for i in target_tests:
                 if not os.path.exists(i["path"]):
-                    raise IOError("test file: %s does not exist" % i["path"])
+                    raise IOError("test file: {} does not exist".format(i["path"]))
 
                 file_ext = os.path.splitext(os.path.split(i['path'])[-1])[-1]
                 test_container = None
 
                 self.add_test(i["path"], i["expected"], test_container)
             return
 
         self.tests.append({'filepath': filepath, 'expected': expected, 'test_container': test_container})
@@ -779,27 +781,28 @@ class BaseSessionTestRunner(object):
 
         for test in tests:
             self.run_test(test['filepath'], test['expected'], test['test_container'])
 
     def run_test_sets(self):
         if len(self.tests) < 1:
             raise Exception('There are no tests to run.')
         elif self.total_chunks > len(self.tests):
-            raise ValueError('Total number of chunks must be between 1 and %d.' % len(self.tests))
+            raise ValueError('Total number of chunks must be between 1 and {}.'
+                             .format(len(self.tests)))
         if self.total_chunks > 1:
             chunks = [[] for i in range(self.total_chunks)]
             for i, test in enumerate(self.tests):
                 target_chunk = i % self.total_chunks
                 chunks[target_chunk].append(test)
 
-            self.logger.info('Running chunk %d of %d (%d tests selected from a '
-                             'total of %d)' % (self.this_chunk, self.total_chunks,
-                                               len(chunks[self.this_chunk - 1]),
-                                               len(self.tests)))
+            self.logger.info('Running chunk {0} of {1} ({2} tests selected from a '
+                             'total of {3})'.format(self.this_chunk, self.total_chunks,
+                                                    len(chunks[self.this_chunk - 1]),
+                                                    len(self.tests)))
             self.tests = chunks[self.this_chunk - 1]
 
         self.run_test_set(self.tests)
 
     def cleanup(self):
         if self.httpd:
             self.httpd.stop()
 
--- a/testing/marionette/harness/session/runner/ping_server.py
+++ b/testing/marionette/harness/session/runner/ping_server.py
@@ -10,17 +10,17 @@ class PingHandler(BaseHTTPServer.BaseHTT
         s.send_header("Content-type", "text/html")
         s.end_headers()
 
     def do_GET(s):
         self.do_HEAD(self, s)
         s.wfile.write("<html>")
         s.wfile.write("  <head><title>Success</title></head>")
         s.wfile.write("  <body>")
-        s.wfile.write("    <p>The server is working correctly. Firefox should send a POST request on port %d</p>" % self.server.port)
+        s.wfile.write("    <p>The server is working correctly. Firefox should send a POST request on port {}</p>".format(self.server.port))
         s.wfile.write("  </body>")
         s.wfile.write("</html>")
 
     def do_POST(s):
         length = int(s.headers["Content-Length"])
         plainData = s.rfile.read(length)
         if s.headers.get("Content-Encoding") == "gzip":
             plainData = zlib.decompress(plainData, zlib.MAX_WBITS | 16)
--- a/testing/marionette/harness/session/session_test.py
+++ b/testing/marionette/harness/session/session_test.py
@@ -214,19 +214,19 @@ class CommonTestCase(unittest.TestCase):
         """
         raise NotImplementedError
 
     @property
     def test_name(self):
         if hasattr(self, 'jsFile'):
             return os.path.basename(self.jsFile)
         else:
-            return '%s.py %s.%s' % (self.__class__.__module__,
-                                    self.__class__.__name__,
-                                    self._testMethodName)
+            return '{0}.py {1}.{2}'.format(self.__class__.__module__,
+                                           self.__class__.__name__,
+                                           self._testMethodName)
 
     def id(self):
         # TBPL starring requires that the "test name" field of a failure message
         # not differ over time. The test name to be used is passed to
         # mozlog via the test id, so this is overriden to maintain
         # consistency.
         return self.test_name
 
@@ -253,17 +253,17 @@ class CommonTestCase(unittest.TestCase):
     def _deleteSession(self):
         if hasattr(self, 'start_time'):
             self.duration = time.time() - self.start_time
         if hasattr(self.marionette, 'session'):
             if self.marionette.session is not None:
                 try:
                     self.loglines.extend(self.marionette.get_logs())
                 except Exception, inst:
-                    self.loglines = [['Error getting log: %s' % inst]]
+                    self.loglines = [['Error getting log: {}'.format(inst)]]
                 try:
                     self.marionette.delete_session()
                 except (socket.error, MarionetteException, IOError):
                     # Gecko has crashed?
                     self.marionette.session = None
                     try:
                         self.marionette.client.close()
                     except socket.error:
@@ -299,17 +299,17 @@ class CommonTestCase(unittest.TestCase):
         '''
         marionette = marionette or self.marionette
         if not os.path.isabs(filename):
             # Find the caller's filename and make the path relative to that.
             caller_file = sys._getframe(1).f_globals.get('__file__', '')
             caller_file = os.path.abspath(caller_file)
             filename = os.path.join(os.path.dirname(caller_file), filename)
         self.assert_(os.path.exists(filename),
-                     'Script "%s" must exist' % filename)
+                     'Script "{}" must exist'.format(filename))
         original_test_name = self.marionette.test_name
         self.marionette.test_name = os.path.basename(filename)
         f = open(filename, 'r')
         js = f.read()
         args = []
 
         head_js = JSTest.head_js_re.search(js);
         if head_js:
@@ -379,17 +379,17 @@ class CommonTestCase(unittest.TestCase):
                     self.logger.test_status(self.test_name, name, 'FAIL',
                                             expected='FAIL', message=diag)
                 for failure in results['unexpectedSuccesses']:
                     diag = "" if failure.get('diag') is None else failure['diag']
                     name = "got true, expected false" if failure.get('name') is None else failure['name']
                     self.logger.test_status(self.test_name, name, 'PASS',
                                             expected='FAIL', message=diag)
                 self.assertEqual(0, len(results['failures']),
-                                 '%d tests failed' % len(results['failures']))
+                                 '{} tests failed'.format(len(results['failures'])))
                 if len(results['unexpectedSuccesses']) > 0:
                     raise _UnexpectedSuccess('')
                 if len(results['expectedFailures']) > 0:
                     raise _ExpectedFailure((AssertionError, AssertionError(''), None))
 
             self.assertTrue(results['passed']
                             + len(results['failures'])
                             + len(results['expectedFailures'])