Bug 1300776 - Add testing/marionette/harness to flake8 linter (except mixins, tests) . r?ahal draft
authorHenrik Skupin <mail@hskupin.info>
Tue, 06 Sep 2016 15:46:08 +0200
changeset 410256 99651056373390cc2e6715a6cb13e67f3af8950c
parent 409737 dbe4b47941c7b3d6298a0ead5e40dd828096c808
child 530543 77a073c8267b62923ecdb9b915ffcbb9efe1885f
push id28698
push userbmo:hskupin@gmail.com
push dateTue, 06 Sep 2016 13:46:35 +0000
reviewersahal
bugs1300776
milestone51.0a1
Bug 1300776 - Add testing/marionette/harness to flake8 linter (except mixins, tests) . r?ahal MozReview-Commit-ID: F9Hfze9zvzE
testing/marionette/harness/.flake8
testing/marionette/harness/docs/conf.py
testing/marionette/harness/marionette/marionette_test.py
testing/marionette/harness/marionette/runner/base.py
testing/marionette/harness/marionette/runtests.py
tools/lint/flake8.lint
new file mode 100644
--- /dev/null
+++ b/testing/marionette/harness/.flake8
@@ -0,0 +1,3 @@
+[flake8]
+max-line-length = 99
+exclude = __init__.py,disti/*,build/*,session/*,marionette/runner/mixins/*, marionette/tests/*
--- a/testing/marionette/harness/docs/conf.py
+++ b/testing/marionette/harness/docs/conf.py
@@ -6,94 +6,95 @@
 # This file is execfile()d with the current directory set to its containing dir.
 #
 # Note that not all possible configuration values are present in this
 # autogenerated file.
 #
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
+import os
+import sys
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+# sys.path.insert(0, os.path.abspath('.'))
 
 here = os.path.dirname(os.path.abspath(__file__))
 parent = os.path.dirname(here)
 sys.path.insert(0, parent)
 
 # -- General configuration -----------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
+# needs_sphinx = '1.0'
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 extensions = ['sphinx.ext.autodoc']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
 # The suffix of source filenames.
 source_suffix = '.rst'
 
 # The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
 
 # The master toctree document.
 master_doc = 'index'
 
 # General information about the project.
 project = u'Marionette Python Client'
 copyright = u'2013, Mozilla Automation and Tools and individual contributors'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-#version = '0'
+# version = '0'
 # The full version, including alpha/beta/rc tags.
-#release = '0'
+# release = '0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
-#language = None
+# language = None
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#today = ''
+# today = ''
 # Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
 exclude_patterns = ['_build']
 
 # The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
+# default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+# show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
 pygments_style = 'sphinx'
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
 
 
 # -- Options for HTML output ---------------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 
 html_theme = 'default'
@@ -107,152 +108,152 @@ if not on_rtd:
         html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
     except ImportError:
         pass
 
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {}
+# html_theme_options = {}
 
 # Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+# html_title = None
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-#html_logo = None
+# html_logo = None
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
 # pixels large.
-#html_favicon = None
+# html_favicon = None
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
+# html_static_path = ['_static']
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Output file base name for HTML help builder.
 htmlhelp_basename = 'MarionettePythonClientdoc'
 
 
 # -- Options for LaTeX output --------------------------------------------------
 
 latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
+    # The paper size ('letterpaper' or 'a4paper').
+    # 'papersize': 'letterpaper',
 
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
+    # The font size ('10pt', '11pt' or '12pt').
+    # 'pointsize': '10pt',
 
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
+    # Additional stuff for the LaTeX preamble.
+    # 'preamble': '',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'MarionettePythonClient.tex', u'Marionette Python Client Documentation',
-   u'Mozilla Automation and Tools team', 'manual'),
+    ('index', 'MarionettePythonClient.tex', u'Marionette Python Client Documentation',
+     u'Mozilla Automation and Tools team', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-#latex_logo = None
+# latex_logo = None
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
 
 
 # -- Options for manual page output --------------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
     ('index', 'marionettepythonclient', u'Marionette Python Client Documentation',
      [u'Mozilla Automation and Tools team'], 1)
 ]
 
 # If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
 
 
 # -- Options for Texinfo output ------------------------------------------------
 
 # Grouping the document tree into Texinfo files. List of tuples
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'MarionettePythonClient', u'Marionette Python Client Documentation',
-   u'Mozilla Automation and Tools team', 'MarionettePythonClient', 'One line description of project.',
-   'Miscellaneous'),
+    ('index', 'MarionettePythonClient', 'Marionette Python Client Documentation',
+     'Mozilla Automation and Tools team', 'MarionettePythonClient',
+     'One line description of project.', 'Miscellaneous'),
 ]
 
 # Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
 
 # If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
 
 # How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
--- a/testing/marionette/harness/marionette/marionette_test.py
+++ b/testing/marionette/harness/marionette/marionette_test.py
@@ -11,128 +11,131 @@ import socket
 import time
 import types
 import unittest
 import weakref
 import warnings
 
 
 from marionette_driver.errors import (
-        MarionetteException, TimeoutException,
-        JavascriptException, NoSuchElementException, NoSuchWindowException,
-        StaleElementException, ScriptTimeoutException, ElementNotVisibleException,
-        NoSuchFrameException, InvalidElementStateException, NoAlertPresentException,
-        InvalidCookieDomainException, UnableToSetCookieException, InvalidSelectorException,
-        MoveTargetOutOfBoundsException
-        )
-from marionette_driver.marionette import Marionette
-from marionette_driver.wait import Wait
-from marionette_driver.expected import element_present, element_not_present
+    MarionetteException,
+    ScriptTimeoutException,
+    TimeoutException,
+)
 from mozlog import get_default_logger
 
 
 class SkipTest(Exception):
     """
     Raise this exception in a test to skip it.
 
     Usually you can use TestResult.skip() or one of the skipping decorators
     instead of raising this directly.
     """
+
     pass
 
+
 class _ExpectedFailure(Exception):
     """
     Raise this when a test is expected to fail.
 
     This is an implementation detail.
     """
 
     def __init__(self, exc_info):
         super(_ExpectedFailure, self).__init__()
         self.exc_info = exc_info
 
+
 class _UnexpectedSuccess(Exception):
-    """
-    The test was supposed to fail, but it didn't!
-    """
+    """The test was supposed to fail, but it didn't."""
+
     pass
 
+
 def skip(reason):
     """Unconditionally skip a test."""
     def decorator(test_item):
         if not isinstance(test_item, (type, types.ClassType)):
             @functools.wraps(test_item)
             def skip_wrapper(*args, **kwargs):
                 raise SkipTest(reason)
             test_item = skip_wrapper
 
         test_item.__unittest_skip__ = True
         test_item.__unittest_skip_why__ = reason
         return test_item
     return decorator
 
+
 def expectedFailure(func):
     @functools.wraps(func)
     def wrapper(*args, **kwargs):
         try:
             func(*args, **kwargs)
         except Exception:
             raise _ExpectedFailure(sys.exc_info())
         raise _UnexpectedSuccess
     return wrapper
 
+
 def skip_if_chrome(target):
     def wrapper(self, *args, **kwargs):
         if self.marionette._send_message("getContext", key="value") == "chrome":
             raise SkipTest("skipping test in chrome context")
         return target(self, *args, **kwargs)
     return wrapper
 
+
 def skip_if_desktop(target):
     def wrapper(self, *args, **kwargs):
         if self.marionette.session_capabilities.get('browserName') == 'firefox':
             raise SkipTest('skipping due to desktop')
         return target(self, *args, **kwargs)
     return wrapper
 
+
 def skip_if_mobile(target):
     def wrapper(self, *args, **kwargs):
         if self.marionette.session_capabilities.get('browserName') == 'fennec':
             raise SkipTest('skipping due to fennec')
         return target(self, *args, **kwargs)
     return wrapper
 
+
 def skip_if_e10s(target):
     def wrapper(self, *args, **kwargs):
         with self.marionette.using_context('chrome'):
             multi_process_browser = self.marionette.execute_script("""
             try {
               return Services.appinfo.browserTabsRemoteAutostart;
             } catch (e) {
               return false;
             }""")
 
         if multi_process_browser:
             raise SkipTest('skipping due to e10s')
         return target(self, *args, **kwargs)
     return wrapper
 
+
 def skip_unless_protocol(predicate):
-    """Given a predicate passed the current protocol level, skip the
-    test if the predicate does not match."""
+    """Skip the 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)
             return test_item(self)
         return skip_wrapper
     return decorator
 
+
 def skip_unless_browser_pref(pref, predicate=bool):
     """
     Skip a test based on the value of a browser preference.
 
     :param pref: the preference name
     :param predicate: a function that should return false to skip the test.
                       The function takes one parameter, the preference value.
                       Defaults to the python built-in bool function.
@@ -154,18 +157,19 @@ def skip_unless_browser_pref(pref, predi
             if value is None:
                 self.fail("No such browser preference: %r" % pref)
             if not predicate(value):
                 raise SkipTest("browser preference %r: %r" % (pref, value))
             return target(self, *args, **kwargs)
         return wrapped
     return wrapper
 
+
 def parameterized(func_suffix, *args, **kwargs):
-    """
+    r"""
     A decorator that can generate methods given a base method and some data.
 
     **func_suffix** is used as a suffix for the new created method and must be
     unique given a base method. if **func_suffix** countains characters that
     are not allowed in normal python function name, these characters will be
     replaced with "_".
 
     This decorator can be used more than once on a single base method. The class
@@ -190,19 +194,21 @@ def parameterized(func_suffix, *args, **
     """
     def wrapped(func):
         if not hasattr(func, 'metaparameters'):
             func.metaparameters = []
         func.metaparameters.append((func_suffix, args, kwargs))
         return func
     return wrapped
 
+
 def with_parameters(parameters):
     """
     A decorator that can generate methods given a base method and some data.
+
     Acts like :func:`parameterized`, but define all methods in one call.
 
     Example::
 
       # This example will generate two methods:
       #
       # - MyTestCase.test_it_1
       # - MyTestCase.test_it_2
@@ -218,50 +224,58 @@ def with_parameters(parameters):
     :param parameters: list of tuples (**func_suffix**, **args**, **kwargs**)
                        defining parameters like in :func:`todo`.
     """
     def wrapped(func):
         func.metaparameters = parameters
         return func
     return wrapped
 
+
 def wraps_parameterized(func, func_suffix, args, kwargs):
-    """Internal: for MetaParameterized"""
+    """Internal: for MetaParameterized."""
     def wrapper(self):
         return func(self, *args, **kwargs)
     wrapper.__name__ = func.__name__ + '_' + str(func_suffix)
     wrapper.__doc__ = '[%s] %s' % (func_suffix, func.__doc__)
     return wrapper
 
+
 class MetaParameterized(type):
     """
-    A metaclass that allow a class to use decorators like :func:`parameterized`
+    A metaclass that allow a class to use decorators.
+
+    It can be used like :func:`parameterized`
     or :func:`with_parameters` to generate new methods.
     """
+
     RE_ESCAPE_BAD_CHARS = re.compile(r'[\.\(\) -/]')
+
     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))
+                                       (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*)['|\"](.*?)['|\"];")
     context_re = re.compile(r"MARIONETTE_CONTEXT(\s*)=(\s*)['|\"](.*?)['|\"];")
     timeout_re = re.compile(r"MARIONETTE_TIMEOUT(\s*)=(\s*)(\d+);")
     inactivity_timeout_re = re.compile(r"MARIONETTE_INACTIVITY_TIMEOUT(\s*)=(\s*)(\d+);")
 
+
 class CommonTestCase(unittest.TestCase):
 
     __metaclass__ = MetaParameterized
     match_re = None
     failureException = AssertionError
     pydebugger = None
 
     def __init__(self, methodName, **kwargs):
@@ -305,21 +319,21 @@ class CommonTestCase(unittest.TestCase):
             startTestRun = getattr(result, 'startTestRun', None)
             if startTestRun is not None:
                 startTestRun()
 
         result.startTest(self)
 
         testMethod = getattr(self, self._testMethodName)
         if (getattr(self.__class__, "__unittest_skip__", False) or
-            getattr(testMethod, "__unittest_skip__", False)):
+                getattr(testMethod, "__unittest_skip__", False)):
             # If the class or method was skipped.
             try:
-                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
-                            or getattr(testMethod, '__unittest_skip_why__', ''))
+                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') or
+                            getattr(testMethod, '__unittest_skip_why__', ''))
                 self._addSkip(result, skip_why)
             finally:
                 result.stopTest(self)
             self.stop_time = time.time()
             return
         try:
             success = False
             try:
@@ -356,17 +370,18 @@ class CommonTestCase(unittest.TestCase):
                     raise
                 except _ExpectedFailure as e:
                     expected_failure(result, e.exc_info)
                 except _UnexpectedSuccess:
                     addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
                     if addUnexpectedSuccess is not None:
                         addUnexpectedSuccess(self)
                     else:
-                        warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
+                        warnings.warn("TestResult has no addUnexpectedSuccess method, "
+                                      "reporting as failures",
                                       RuntimeWarning)
                         result.addFailure(self, sys.exc_info())
                 except SkipTest as e:
                     self._addSkip(result, str(e))
                 except:
                     self._enter_pm()
                     result.addError(self, sys.exc_info())
                 else:
@@ -397,31 +412,28 @@ class CommonTestCase(unittest.TestCase):
             result.stopTest(self)
             if orig_result is None:
                 stopTestRun = getattr(result, 'stopTestRun', None)
                 if stopTestRun is not None:
                     stopTestRun()
 
     @classmethod
     def match(cls, filename):
-        """
-        Determines if the specified filename should be handled by this
-        test class; this is done by looking for a match for the filename
-        using cls.match_re.
+        """Determine if the specified filename should be handled by this test class.
+
+        This is done by looking for a match for the filename using cls.match_re.
         """
         if not cls.match_re:
             return False
         m = cls.match_re.match(filename)
         return m is not None
 
     @classmethod
     def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette, testvars):
-        """
-        Adds all the tests in the specified file to the specified suite.
-        """
+        """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__,
@@ -475,59 +487,59 @@ class CommonTestCase(unittest.TestCase):
                         self.marionette.client.close()
                     except socket.error:
                         pass
         self.marionette = None
 
     def setup_SpecialPowers_observer(self):
         self.marionette.set_context("chrome")
         self.marionette.execute_script("""
-            let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
-            Components.utils.import("resource://gre/modules/Preferences.jsm");
-            Preferences.set(SECURITY_PREF, true);
+let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
+Components.utils.import("resource://gre/modules/Preferences.jsm");
+Preferences.set(SECURITY_PREF, true);
 
-            if (!testUtils.hasOwnProperty("specialPowersObserver")) {
-              let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-                .getService(Components.interfaces.mozIJSSubScriptLoader);
-              loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.jsm",
-                testUtils);
-              testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
-              testUtils.specialPowersObserver.init();
-            }
-            """)
+if (!testUtils.hasOwnProperty("specialPowersObserver")) {
+  let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
+    .getService(Components.interfaces.mozIJSSubScriptLoader);
+  loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.jsm",
+    testUtils);
+  testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
+  testUtils.specialPowersObserver.init();
+}
+""")
 
     def run_js_test(self, filename, marionette=None):
-        '''
-        Run a JavaScript test file and collect its set of assertions
-        into the current test's results.
+        """Run a JavaScript test file.
+
+        It collects its set of assertions into the current test's results.
 
         :param filename: The path to the JavaScript test file to execute.
                          May be relative to the current script.
         :param marionette: The Marionette object in which to execute the test.
                            Defaults to self.marionette.
-        '''
+        """
         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)
         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);
+        head_js = JSTest.head_js_re.search(js)
         if head_js:
             head_js = head_js.group(3)
             head = open(os.path.join(os.path.dirname(filename), head_js), 'r')
-            js = head.read() + js;
+            js = head.read() + js
 
         context = JSTest.context_re.search(js)
         if context:
             context = context.group(3)
         else:
             context = 'content'
 
         if 'SpecialPowers' in js:
@@ -563,78 +575,81 @@ class CommonTestCase(unittest.TestCase):
         try:
             results = marionette.execute_js_script(
                 js,
                 args,
                 inactivity_timeout=inactivity_timeout,
                 filename=os.path.basename(filename)
             )
 
-            self.assertTrue(not 'timeout' in filename,
+            self.assertTrue('timeout' not in filename,
                             'expected timeout not triggered')
 
             if 'fail' in filename:
                 self.assertTrue(len(results['failures']) > 0,
                                 "expected test failures didn't occur")
             else:
                 for failure in results['failures']:
                     diag = "" if failure.get('diag') is None else failure['diag']
-                    name = "got false, expected true" if failure.get('name') is None else failure['name']
+                    name = ("got false, expected true" if failure.get('name') is None else
+                            failure['name'])
                     self.logger.test_status(self.test_name, name, 'FAIL',
                                             message=diag)
                 for failure in results['expectedFailures']:
                     diag = "" if failure.get('diag') is None else failure['diag']
-                    name = "got false, expected false" if failure.get('name') is None else failure['name']
+                    name = ("got false, expected false" if failure.get('name') is None else
+                            failure['name'])
                     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']
+                    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']))
                 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'])
-                            + len(results['unexpectedSuccesses']) > 0,
+            self.assertTrue(results['passed'] +
+                            len(results['failures']) +
+                            len(results['expectedFailures']) +
+                            len(results['unexpectedSuccesses']) > 0,
                             'no tests run')
 
         except ScriptTimeoutException:
             if 'timeout' in filename:
                 # expected exception
                 pass
             else:
                 self.loglines = marionette.get_logs()
                 raise
         self.marionette.test_name = original_test_name
 
 
-
 class MarionetteTestCase(CommonTestCase):
 
     match_re = re.compile(r"test_(.*)\.py$")
 
     def __init__(self, marionette_weakref, methodName='runTest',
                  filepath='', **kwargs):
         self._marionette_weakref = marionette_weakref
         self.marionette = None
         self.methodName = methodName
         self.filepath = filepath
         self.testvars = kwargs.pop('testvars', None)
         self.test_container = kwargs.pop('test_container', None)
         CommonTestCase.__init__(self, methodName, **kwargs)
 
     @classmethod
-    def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette, testvars, **kwargs):
+    def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette,
+                           testvars, **kwargs):
         # since we use imp.load_source to load test modules, if a module
         # is loaded with the same name as another one the module would just be
         # reloaded.
         #
         # We may end up by finding too many test in a module then since
         # reload() only update the module dict (so old keys are still there!)
         # see https://docs.python.org/2/library/functions.html#reload
         #
@@ -644,17 +659,17 @@ class MarionetteTestCase(CommonTestCase)
         if mod_name in sys.modules:
             del sys.modules[mod_name]
 
         test_mod = imp.load_source(mod_name, filepath)
 
         for name in dir(test_mod):
             obj = getattr(test_mod, name)
             if (isinstance(obj, (type, types.ClassType)) and
-                issubclass(obj, unittest.TestCase)):
+                    issubclass(obj, unittest.TestCase)):
                 testnames = testloader.getTestCaseNames(obj)
                 for testname in testnames:
                     suite.addTest(obj(weakref.ref(marionette),
                                   methodName=testname,
                                   filepath=filepath,
                                   testvars=testvars,
                                   **kwargs))
 
@@ -691,30 +706,32 @@ class MarionetteTestCase(CommonTestCase)
         while time.time() < timeout:
             value = method(self.marionette)
             if value:
                 return value
             time.sleep(0.5)
         else:
             raise TimeoutException("wait_for_condition timed out")
 
+
 class MarionetteJSTestCase(CommonTestCase):
 
     match_re = re.compile(r"test_(.*)\.js$")
 
     def __init__(self, marionette_weakref, methodName='runTest', jsFile=None, **kwargs):
         assert(jsFile)
         self.jsFile = jsFile
         self._marionette_weakref = marionette_weakref
         self.marionette = None
         self.test_container = kwargs.pop('test_container', None)
         CommonTestCase.__init__(self, methodName)
 
     @classmethod
-    def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, marionette, testvars, **kwargs):
+    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('\\', '\\\\'),
             sandbox="simpletest")
--- a/testing/marionette/harness/marionette/runner/base.py
+++ b/testing/marionette/harness/marionette/runner/base.py
@@ -28,19 +28,19 @@ from moztest.adapters.unit import Struct
 from moztest.results import TestResultCollection, TestResult, relevant_line
 import mozversion
 
 import httpd
 
 
 here = os.path.abspath(os.path.dirname(__file__))
 
+
 def update_mozinfo(path=None):
-    """walk up directories to find mozinfo.json and update the info"""
-
+    """Walk up directories to find mozinfo.json and update the info."""
     path = path or here
     dirs = set()
     while path != os.path.expanduser('~'):
         if path in dirs:
             break
         dirs.add(path)
         path = os.path.split(path)[0]
 
@@ -53,26 +53,27 @@ class MarionetteTest(TestResult):
     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)
         else:
             return self.name
 
+
 class MarionetteTestResult(StructuredTestResult, TestResultCollection):
 
     resultClass = MarionetteTest
 
     def __init__(self, *args, **kwargs):
         self.marionette = kwargs.pop('marionette')
         TestResultCollection.__init__(self, 'MarionetteTest')
         self.passed = 0
         self.testsRun = 0
-        self.result_modifiers = [] # used by mixins to modify the result
+        self.result_modifiers = []  # used by mixins to modify the result
         StructuredTestResult.__init__(self, *args, **kwargs)
 
     @property
     def skipped(self):
         return [t for t in self if t.result == 'SKIPPED']
 
     @skipped.setter
     def skipped(self, value):
@@ -128,33 +129,36 @@ class MarionetteTestResult(StructuredTes
 
         name = str(test).split()[0]
         test_class = get_class(test)
         if hasattr(test, 'jsFile'):
             name = os.path.basename(test.jsFile)
             test_class = None
 
         t = self.resultClass(name=name, test_class=test_class,
-                       time_start=test.start_time, result_expected=result_expected,
-                       context=context, **kwargs)
+                             time_start=test.start_time, result_expected=result_expected,
+                             context=context, **kwargs)
         # call any registered result modifiers
         for modifier in self.result_modifiers:
-            result_expected, result_actual, output, context = modifier(t, result_expected, result_actual, output, context)
+            result_expected, result_actual, output, context = modifier(
+                t, result_expected, result_actual, output, context)
         t.finish(result_actual,
                  time_end=time.time() if test.start_time else 0,
                  reason=relevant_line(output),
                  output=output)
         self.append(t)
 
     def addError(self, test, err):
-        self.add_test_result(test, output=self._exc_info_to_string(err, test), result_actual='ERROR')
+        self.add_test_result(test, output=self._exc_info_to_string(err, test),
+                             result_actual='ERROR')
         super(MarionetteTestResult, self).addError(test, err)
 
     def addFailure(self, test, err):
-        self.add_test_result(test, output=self._exc_info_to_string(err, test), result_actual='UNEXPECTED-FAIL')
+        self.add_test_result(test, output=self._exc_info_to_string(err, test),
+                             result_actual='UNEXPECTED-FAIL')
         super(MarionetteTestResult, self).addFailure(test, err)
 
     def addSuccess(self, test):
         self.passed += 1
         self.add_test_result(test, result_actual='PASS')
         super(MarionetteTestResult, self).addSuccess(test)
 
     def addExpectedFailure(self, test, err):
@@ -188,17 +192,17 @@ class MarionetteTestResult(StructuredTes
     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
                 for line in testcase.loglines:
                     str_line = ' '.join(line)
-                    if not 'TEST-END' in str_line and not 'TEST-START' in str_line:
+                    if 'TEST-END' not in str_line and 'TEST-START' not in str_line:
                         skip_log = False
                         break
                 if skip_log:
                     return
                 self.logger.info('START LOG:')
                 for line in testcase.loglines:
                     self.logger.info(' '.join(line).encode('ascii', 'replace'))
                 self.logger.info('END LOG:')
@@ -255,126 +259,131 @@ class BaseMarionetteArguments(ArgumentPa
                           nargs='*',
                           default=[],
                           help='Tests to run. '
                                'One or more paths to test files (Python or JS), '
                                'manifest files (.ini) or directories. '
                                'When a directory is specified, '
                                'all test files in the directory will be run.')
         self.add_argument('--binary',
-                        help='path to gecko executable to launch before running the test')
+                          help='path to gecko executable to launch before running the test')
         self.add_argument('--address',
-                        help='host:port of running Gecko instance to connect to')
+                          help='host:port of running Gecko instance to connect to')
         self.add_argument('--emulator',
-                        action='store_true',
-                        help='If no --address is given, then the harness will launch an emulator. (See Remote options group.) '
-                             'If --address is given, then the harness assumes you are running an '
-                             'emulator already, and will launch gecko app on  that emulator.')
+                          action='store_true',
+                          help='If no --address is given, then the harness will launch an '
+                               'emulator. (See Remote options group.) '
+                               'If --address is given, then the harness assumes you are '
+                               'running an emulator already, and will launch gecko app '
+                               'on that emulator.')
         self.add_argument('--app',
-                        help='application to use. see marionette_driver.geckoinstance')
+                          help='application to use. see marionette_driver.geckoinstance')
         self.add_argument('--app-arg',
-                        dest='app_args',
-                        action='append',
-                        default=[],
-                        help='specify a command line argument to be passed onto the application')
+                          dest='app_args',
+                          action='append',
+                          default=[],
+                          help='specify a command line argument to be passed onto the application')
         self.add_argument('--profile',
-                        help='profile to use when launching the gecko process. If not passed, then a profile will be '
-                             'constructed and used',
-                        type=dir_path)
+                          help='profile to use when launching the gecko process. If not passed, '
+                               'then a profile will be constructed and used',
+                          type=dir_path)
         self.add_argument('--pref',
-                        action='append',
-                        dest='prefs_args',
-                        help=(" A preference to set. Must be a key-value pair"
-                              " separated by a ':'."))
+                          action='append',
+                          dest='prefs_args',
+                          help="A preference to set. Must be a key-value pair separated by a ':'.")
         self.add_argument('--preferences',
-                        action='append',
-                        dest='prefs_files',
-                        help=("read preferences from a JSON or INI file. For"
-                              " INI, use 'file.ini:section' to specify a"
-                              " particular section."))
+                          action='append',
+                          dest='prefs_files',
+                          help="read preferences from a JSON or INI file. For INI, use "
+                               "'file.ini:section' to specify a particular section.")
         self.add_argument('--addon',
-                        action='append',
-                        help="addon to install; repeat for multiple addons.")
+                          action='append',
+                          help="addon to install; repeat for multiple addons.")
         self.add_argument('--repeat',
-                        type=int,
-                        default=0,
-                        help='number of times to repeat the test(s)')
+                          type=int,
+                          default=0,
+                          help='number of times to repeat the test(s)')
         self.add_argument('--testvars',
-                        action='append',
-                        help='path to a json file with any test data required')
+                          action='append',
+                          help='path to a json file with any test data required')
         self.add_argument('--symbols-path',
-                        help='absolute path to directory containing breakpad symbols, or the url of a zip file containing symbols')
+                          help='absolute path to directory containing breakpad symbols, or the '
+                               'url of a zip file containing symbols')
         self.add_argument('--timeout',
-                        type=int,
-                        help='if a --timeout value is given, it will set the default page load timeout, search timeout and script timeout to the given value. If not passed in, it will use the default values of 30000ms for page load, 0ms for search timeout and 10000ms for script timeout')
+                          type=int,
+                          help='if a --timeout value is given, it will set the default page load '
+                               'timeout, search timeout and script timeout to the given value. '
+                               'If not passed in, it will use the default values of 30000ms for '
+                               'page load, 0ms for search timeout and 10000ms for script timeout')
         self.add_argument('--startup-timeout',
-                        type=int,
-                        default=60,
-                        help='the max number of seconds to wait for a Marionette connection after launching a binary')
+                          type=int,
+                          default=60,
+                          help='the max number of seconds to wait for a Marionette connection '
+                               'after launching a binary')
         self.add_argument('--shuffle',
-                        action='store_true',
-                        default=False,
-                        help='run tests in a random order')
+                          action='store_true',
+                          default=False,
+                          help='run tests in a random order')
         self.add_argument('--shuffle-seed',
-                        type=int,
-                        default=random.randint(0, sys.maxint),
-                        help='Use given seed to shuffle tests')
+                          type=int,
+                          default=random.randint(0, sys.maxint),
+                          help='Use given seed to shuffle tests')
         self.add_argument('--total-chunks',
-                        type=int,
-                        help='how many chunks to split the tests up into')
+                          type=int,
+                          help='how many chunks to split the tests up into')
         self.add_argument('--this-chunk',
-                        type=int,
-                        help='which chunk to run')
+                          type=int,
+                          help='which chunk to run')
         self.add_argument('--sources',
-                        help='path to sources.xml (Firefox OS only)')
+                          help='path to sources.xml (Firefox OS only)')
         self.add_argument('--server-root',
-                        help='url to a webserver or path to a document root from which content '
-                        'resources are served (default: {}).'.format(os.path.join(
-                            os.path.dirname(here), 'www')))
+                          help='url to a webserver or path to a document root from which content '
+                               'resources are served (default: {}).'.format(os.path.join(
+                                   os.path.dirname(here), 'www')))
         self.add_argument('--gecko-log',
-                        help="Define the path to store log file. If the path is"
-                             " a directory, the real log file will be created"
-                             " given the format gecko-(timestamp).log. If it is"
-                             " a file, if will be used directly. '-' may be passed"
-                             " to write to stdout. Default: './gecko.log'")
+                          help="Define the path to store log file. If the path is"
+                               " a directory, the real log file will be created"
+                               " given the format gecko-(timestamp).log. If it is"
+                               " a file, if will be used directly. '-' may be passed"
+                               " to write to stdout. Default: './gecko.log'")
         self.add_argument('--logger-name',
-                        default='Marionette-based Tests',
-                        help='Define the name to associate with the logger used')
+                          default='Marionette-based Tests',
+                          help='Define the name to associate with the logger used')
         self.add_argument('--jsdebugger',
-                        action='store_true',
-                        default=False,
-                        help='Enable the jsdebugger for marionette javascript.')
+                          action='store_true',
+                          default=False,
+                          help='Enable the jsdebugger for marionette javascript.')
         self.add_argument('--pydebugger',
-                        help='Enable python post-mortem debugger when a test fails.'
-                             ' Pass in the debugger you want to use, eg pdb or ipdb.')
+                          help='Enable python post-mortem debugger when a test fails.'
+                               ' Pass in the debugger you want to use, eg pdb or ipdb.')
         self.add_argument('--socket-timeout',
-                        type=float,
-                        default=self.socket_timeout_default,
-                        help='Set the global timeout for marionette socket operations.')
+                          type=float,
+                          default=self.socket_timeout_default,
+                          help='Set the global timeout for marionette socket operations.')
         self.add_argument('--disable-e10s',
-                        action='store_false',
-                        dest='e10s',
-                        default=True,
-                        help='Disable e10s when running marionette tests.')
+                          action='store_false',
+                          dest='e10s',
+                          default=True,
+                          help='Disable e10s when running marionette tests.')
         self.add_argument('--tag',
-                        action='append', dest='test_tags',
-                        default=None,
-                        help="Filter out tests that don't have the given tag. Can be "
-                             "used multiple times in which case the test must contain "
-                             "at least one of the given tags.")
+                          action='append', dest='test_tags',
+                          default=None,
+                          help="Filter out tests that don't have the given tag. Can be "
+                               "used multiple times in which case the test must contain "
+                               "at least one of the given tags.")
         self.add_argument('--workspace',
                           action='store',
                           default=None,
                           help="Path to directory for Marionette output. "
                                "(Default: .) (Default profile dest: TMP)",
                           type=dir_path)
         self.add_argument('-v', '--verbose',
-                        action='count',
-                        help='Increase verbosity to include debug messages with -v, '
-                            'and trace messages with -vv.')
+                          action='count',
+                          help='Increase verbosity to include debug messages with -v, '
+                               'and trace messages with -vv.')
         self.register_argument_container(RemoteMarionetteArguments())
 
     def register_argument_container(self, container):
         group = self.add_argument_group(container.name)
 
         for cli, kwargs in container.args:
             group.add_argument(*cli, **kwargs)
 
@@ -383,19 +392,17 @@ class BaseMarionetteArguments(ArgumentPa
     def parse_known_args(self, args=None, namespace=None):
         args, remainder = ArgumentParser.parse_known_args(self, args, namespace)
         for container in self.argument_containers:
             if hasattr(container, 'parse_args_handler'):
                 container.parse_args_handler(args)
         return (args, remainder)
 
     def _get_preferences(self, prefs_files, prefs_args):
-        """
-        return user defined profile preferences as a dict
-        """
+        """Return user defined profile preferences as a dict."""
         # object that will hold the preferences
         prefs = mozprofile.prefs.Preferences()
 
         # add preferences files
         if prefs_files:
             for prefs_file in prefs_files:
                 prefs.add_file(prefs_file)
 
@@ -453,16 +460,17 @@ class BaseMarionetteArguments(ArgumentPa
             })
 
         for container in self.argument_containers:
             if hasattr(container, 'verify_usage_handler'):
                 container.verify_usage_handler(args)
 
         return args
 
+
 class RemoteMarionetteArguments(object):
     name = 'Remote (Emulator/Device)'
     args = [
         [['--emulator-binary'],
          {'help': 'Path to emulator binary. By default mozrunner uses `which emulator`',
           'dest': 'emulator_bin',
           }],
         [['--adb'],
@@ -483,27 +491,29 @@ class RemoteMarionetteArguments(object):
           }],
         [['--package'],
          {'help': 'Name of Android package, e.g. org.mozilla.fennec',
           'dest': 'package_name',
           }],
 
     ]
 
+
 class BaseMarionetteTestRunner(object):
 
     textrunnerclass = MarionetteTextTestRunner
     driverclass = Marionette
 
     def __init__(self, address=None,
                  app=None, app_args=None, binary=None, profile=None,
                  logger=None, logdir=None,
                  repeat=0, testvars=None,
                  symbols_path=None, timeout=None,
-                 shuffle=False, shuffle_seed=random.randint(0, sys.maxint), this_chunk=1, total_chunks=1, sources=None,
+                 shuffle=False, shuffle_seed=random.randint(0, sys.maxint), this_chunk=1,
+                 total_chunks=1, sources=None,
                  server_root=None, gecko_log=None, result_callbacks=None,
                  prefs=None, test_tags=None,
                  socket_timeout=BaseMarionetteArguments.socket_timeout_default,
                  startup_timeout=None, addons=None, workspace=None,
                  verbose=0, e10s=True, emulator=False, **kwargs):
         self.extra_kwargs = kwargs
         self.test_kwargs = deepcopy(kwargs)
         self.address = address
@@ -544,17 +554,18 @@ class BaseMarionetteTestRunner(object):
         self.verbose = verbose
         self.e10s = e10s
         self._filename_pattern = None
 
         def gather_debug(test, status):
             rv = {}
             marionette = test._marionette_weakref()
 
-            # In the event we're gathering debug without starting a session, skip marionette commands
+            # In the event we're gathering debug without starting a session,
+            # skip marionette commands
             if marionette.session is not None:
                 try:
                     with marionette.using_context(marionette.CONTEXT_CHROME):
                         rv['screenshot'] = marionette.screenshot()
                     with marionette.using_context(marionette.CONTEXT_CONTENT):
                         rv['source'] = marionette.page_source
                 except Exception:
                     logger = get_default_logger()
@@ -579,29 +590,30 @@ class BaseMarionetteTestRunner(object):
         else:
             self.gecko_log = gecko_log
 
         self.results = []
 
     @property
     def filename_pattern(self):
         if self._filename_pattern is None:
-            self._filename_pattern = re.compile("^test(((_.+?)+?\.((py)|(js)))|(([A-Z].*?)+?\.js))$")
+            self._filename_pattern = re.compile(
+                "^test(((_.+?)+?\.((py)|(js)))|(([A-Z].*?)+?\.js))$")
 
         return self._filename_pattern
 
     @property
     def testvars(self):
         if self._testvars is not None:
             return self._testvars
 
         self._testvars = {}
 
         def update(d, u):
-            """ Update a dictionary that may contain nested dictionaries. """
+            """Update a dictionary that may contain nested dictionaries."""
             for k, v in u.iteritems():
                 o = d.get(k, {})
                 if isinstance(v, dict) and isinstance(o, dict):
                     d[k] = update(d.get(k, {}), v)
                 else:
                     d[k] = u[k]
             return d
 
@@ -662,18 +674,17 @@ class BaseMarionetteTestRunner(object):
         return self._appName
 
     @property
     def bin(self):
         return self._bin
 
     @bin.setter
     def bin(self, path):
-        """
-        Set binary and reset parts of runner accordingly
+        """Set binary and reset parts of runner accordingly.
 
         Intended use: to change binary between calls to run_tests
         """
         self._bin = path
         self.tests = []
         self.cleanup()
 
     def reset_test_stats(self):
@@ -708,17 +719,17 @@ class BaseMarionetteTestRunner(object):
                 'gecko_log': self.gecko_log,
                 # ensure Marionette class takes care of starting gecko instance
                 'bin': True,
             })
 
         if self.bin:
             kwargs.update({
                 'bin': self.bin,
-        })
+            })
 
         if self.emulator:
             kwargs.update({
                 'avd_home': self.extra_kwargs.get('avd_home'),
                 'adb_path': self.extra_kwargs.get('adb_path'),
                 'emulator_binary': self.extra_kwargs.get('emulator_bin'),
                 'avd': self.extra_kwargs.get('avd'),
                 'package_name': self.extra_kwargs.get('package_name'),
@@ -731,35 +742,36 @@ class BaseMarionetteTestRunner(object):
                 'port': int(port),
             })
             if self.emulator:
                 kwargs.update({
                     'connect_to_running_emulator': True,
                 })
             if not self.bin and not self.emulator:
                 try:
-                    #establish a socket connection so we can vertify the data come back
-                    connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
-                    connection.connect((host,int(port)))
+                    # Establish a socket connection so we can vertify the data come back
+                    connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+                    connection.connect((host, int(port)))
                     connection.close()
                 except Exception as e:
                     exc, val, tb = sys.exc_info()
                     msg = "Connection attempt to {0}:{1} failed with error: {2}"
                     raise exc, msg.format(host, port, e), tb
         if self.workspace:
             kwargs['workspace'] = self.workspace_path
         return kwargs
 
     def launch_test_container(self):
         if self.marionette.session is None:
             self.marionette.start_session()
         self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
 
         result = self.marionette.execute_async_script("""
-if((navigator.mozSettings == undefined) || (navigator.mozSettings == null) || (navigator.mozApps == undefined) || (navigator.mozApps == null)) {
+if((navigator.mozSettings == undefined) || (navigator.mozSettings == null) ||
+   (navigator.mozApps == undefined) || (navigator.mozApps == null)) {
     marionetteScriptFinished(false);
     return;
 }
 let setReq = navigator.mozSettings.createLock().set({'lockscreen.enabled': false});
 setReq.onsuccess = function() {
     let appName = 'Test Container';
     let activeApp = window.wrappedJSObject.Service.currentApp;
 
@@ -832,17 +844,18 @@ setReq.onerror = function() {
             else:
                 self.marionette.baseurl = self.server_root
                 self.logger.info("using remote content from %s" % 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'])]
+        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))
 
     def _is_filename_valid(self, filename):
         filename = os.path.basename(filename)
@@ -868,34 +881,34 @@ setReq.onerror = function() {
 
         device_info = None
         if self.marionette.instance and self.emulator:
             try:
                 device_info = self.marionette.instance.runner.device.dm.getInfo()
             except Exception:
                 self.logger.warning('Could not get device info.')
 
-		#TODO Get version_info in Fennec case
+        # TODO: Get version_info in Fennec case
         version_info = None
         if self.bin:
             version_info = mozversion.get_version(binary=self.bin,
                                                   sources=self.sources)
 
         self.logger.info("running with e10s: {}".format(self.e10s))
 
         self.logger.suite_start(self.tests,
                                 version_info=version_info,
                                 device_info=device_info)
 
         self._log_skipped_tests()
 
         interrupted = None
         try:
             counter = self.repeat
-            while counter >=0:
+            while counter >= 0:
                 round_num = self.repeat - counter
                 if round_num > 0:
                     self.logger.info('\nREPEAT %d\n-------' % 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.
@@ -931,30 +944,31 @@ setReq.onerror = function() {
                 raise interrupted[0], interrupted[1], interrupted[2]
 
     def _print_summary(self, tests):
         self.logger.info('\nSUMMARY\n-------')
         self.logger.info('passed: %d' % self.passed)
         if self.unexpected_successes == 0:
             self.logger.info('failed: %d' % self.failed)
         else:
-            self.logger.info('failed: %d (unexpected sucesses: %d)' % (self.failed, self.unexpected_successes))
+            self.logger.info('failed: %d (unexpected sucesses: %d)' %
+                             (self.failed, self.unexpected_successes))
         if self.skipped == 0:
             self.logger.info('todo: %d' % self.todo)
         else:
             self.logger.info('todo: %d (skipped: %d)' % (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])
 
     def start_httpd(self, need_external_ip):
         warnings.warn("start_httpd has been deprecated in favour of create_httpd",
-            DeprecationWarning)
+                      DeprecationWarning)
         self.httpd = self.create_httpd(need_external_ip)
 
     def create_httpd(self, need_external_ip):
         host = "127.0.0.1"
         if need_external_ip:
             host = moznetwork.get_ip()
         root = self.server_root or os.path.join(os.path.dirname(here), "www")
         rv = httpd.FixtureServer(root, host=host)
@@ -972,39 +986,38 @@ setReq.onerror = function() {
                                     " See --help for details.")
                         relpath = os.path.relpath(os.path.join(root, filename), filepath)
                         self.logger.warning(msg_tmpl.format(relpath, filepath))
                     elif self._is_filename_valid(filename):
                         test_file = os.path.join(root, filename)
                         self.add_test(test_file)
             return
 
-
         file_ext = os.path.splitext(os.path.split(filepath)[-1])[1]
 
         if file_ext == '.ini':
             manifest = TestManifest()
             manifest.read(filepath)
 
             filters = []
             if self.test_tags:
                 filters.append(tags(self.test_tags))
-            json_path = update_mozinfo(filepath)
+            update_mozinfo(filepath)
             self.logger.info("mozinfo updated with the following: {}".format(None))
             self.logger.info("mozinfo is: {}".format(mozinfo.info))
             manifest_tests = manifest.active_tests(exists=False,
                                                    disabled=True,
                                                    filters=filters,
                                                    app=self.appName,
                                                    e10s=self.e10s,
                                                    **mozinfo.info)
             if len(manifest_tests) == 0:
-                self.logger.error("no tests to run using specified "
+                self.logger.error("No tests to run using specified "
                                   "combination of filters: {}".format(
-                                       manifest.fmt_filters()))
+                                      manifest.fmt_filters()))
 
             target_tests = []
             for test in manifest_tests:
                 if test.get('disabled'):
                     self.manifest_skipped_tests.append(test)
                 else:
                     target_tests.append(test)
 
@@ -1013,17 +1026,18 @@ setReq.onerror = function() {
                     raise IOError("test file: %s does not exist" % 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})
+        self.tests.append({'filepath': filepath, 'expected': expected,
+                          'test_container': test_container})
 
     def run_test(self, filepath, expected, test_container):
 
         testloader = unittest.TestLoader()
         suite = unittest.TestSuite()
         self.test_kwargs['expected'] = expected
         self.test_kwargs['test_container'] = test_container
         mod_name = os.path.splitext(os.path.split(filepath)[-1])[0]
@@ -1051,22 +1065,24 @@ setReq.onerror = function() {
             self.results.append(results)
 
             self.failed += len(results.failures) + len(results.errors)
             if hasattr(results, 'skipped'):
                 self.skipped += len(results.skipped)
                 self.todo += len(results.skipped)
             self.passed += results.passed
             for failure in results.failures + results.errors:
-                self.failures.append((results.getInfo(failure), failure.output, 'TEST-UNEXPECTED-FAIL'))
+                self.failures.append((results.getInfo(failure), failure.output,
+                                      'TEST-UNEXPECTED-FAIL'))
             if hasattr(results, 'unexpectedSuccesses'):
                 self.failed += len(results.unexpectedSuccesses)
                 self.unexpected_successes += len(results.unexpectedSuccesses)
                 for failure in results.unexpectedSuccesses:
-                    self.failures.append((results.getInfo(failure), failure.output, 'TEST-UNEXPECTED-PASS'))
+                    self.failures.append((results.getInfo(failure), failure.output,
+                                          'TEST-UNEXPECTED-PASS'))
             if hasattr(results, 'expectedFailures'):
                 self.todo += len(results.expectedFailures)
 
             self.mixin_run_tests = []
             for result in self.results:
                 result.result_modifiers = []
 
     def run_test_set(self, tests):
--- a/testing/marionette/harness/marionette/runtests.py
+++ b/testing/marionette/harness/marionette/runtests.py
@@ -34,24 +34,25 @@ class MarionetteHarness(object):
                  testcase_class=MarionetteTestCase,
                  args=None):
         self._runner_class = runner_class
         self._parser_class = parser_class
         self._testcase_class = testcase_class
         self.args = args or self.parse_args()
 
     def parse_args(self, logger_defaults=None):
-        parser = self._parser_class(usage='%(prog)s [options] test_file_or_dir <test_file_or_dir> ...')
+        parser = self._parser_class(
+            usage='%(prog)s [options] test_file_or_dir <test_file_or_dir> ...')
         parser.add_argument('--version', action='version',
-            help="Show version information.",
-            version="%(prog)s {version}"
-                    " (using marionette-driver: {driver_version}, ".format(
-                        version=__version__,
-                        driver_version=driver_version
-                    ))
+                            help="Show version information.",
+                            version="%(prog)s {version}"
+                            " (using marionette-driver: {driver_version}, ".format(
+                                version=__version__,
+                                driver_version=driver_version
+                            ))
         mozlog.commandline.add_logging_group(parser)
         args = parser.parse_args()
         parser.verify_usage(args)
 
         logger = mozlog.commandline.setup_logging(
             args.logger_name, args, logger_defaults or {"tbpl": sys.stdout})
 
         args.logger = logger
--- a/tools/lint/flake8.lint
+++ b/tools/lint/flake8.lint
@@ -126,16 +126,17 @@ def lint(files, **lintargs):
 LINTER = {
     'name': "flake8",
     'description': "Python linter",
     'include': [
         'python/mozlint',
         'taskcluster',
         'testing/firefox-ui',
         'testing/marionette/client',
+        'testing/marionette/harness',
         'testing/puppeteer',
         'testing/talos/',
         'tools/lint',
     ],
     'exclude': [],
     'extensions': EXTENSIONS,
     'type': 'external',
     'payload': lint,