Bug 1277672: Lint Marionette Driver python files r?maja_zf draft
authorDavid Burns <dburns@mozilla.com>
Thu, 02 Jun 2016 21:33:03 +0100
changeset 374998 708d3b0aa0a59d0cf5e2b988667646f88abd82b2
parent 374997 bbb1cc4821302a2a3b8bf5a3c81afdb4c9d1ae62
child 374999 68c8995054ddc6bea829c22f1a98919af969d349
push id20143
push userdburns@mozilla.com
push dateFri, 03 Jun 2016 07:21:16 +0000
reviewersmaja_zf
bugs1277672
milestone49.0a1
Bug 1277672: Lint Marionette Driver python files r?maja_zf Clean code makes everyone happier... MozReview-Commit-ID: LPzH6lMZb6U
testing/marionette/client/marionette_driver/addons.py
testing/marionette/client/marionette_driver/date_time_value.py
testing/marionette/client/marionette_driver/decorators.py
testing/marionette/client/marionette_driver/errors.py
testing/marionette/client/marionette_driver/expected.py
testing/marionette/client/marionette_driver/geckoinstance.py
testing/marionette/client/marionette_driver/gestures.py
testing/marionette/client/marionette_driver/keys.py
testing/marionette/client/marionette_driver/marionette.py
testing/marionette/client/marionette_driver/transport.py
testing/marionette/client/marionette_driver/wait.py
--- a/testing/marionette/client/marionette_driver/addons.py
+++ b/testing/marionette/client/marionette_driver/addons.py
@@ -49,17 +49,18 @@ class Addons(object):
         :param temp: Install a temporary addon. Temporary addons will
                      automatically be uninstalled on shutdown and do not need
                      to be signed, though they must be restartless.
         :returns: The addon ID string of the newly installed addon.
         :raises: :exc:`AddonInstallException`
         """
         with self._mn.using_context('chrome'):
             addon_id, status = self._mn.execute_async_script("""
-              let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm").FileUtils;
+              let fileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm");
+              let FileUtils = fileUtils.FileUtils;
               Components.utils.import("resource://gre/modules/AddonManager.jsm");
               let listener = {
                 onInstallEnded: function(install, addon) {
                   marionetteScriptFinished([addon.id, 0]);
                 },
 
                 onInstallFailed: function(install) {
                   marionetteScriptFinished([null, install.error]);
--- a/testing/marionette/client/marionette_driver/date_time_value.py
+++ b/testing/marionette/client/marionette_driver/date_time_value.py
@@ -1,12 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
+
 class DateTimeValue(object):
     """
     Interface for setting the value of HTML5 "date" and "time" input elements.
 
     Simple usage example:
 
     ::
 
@@ -41,9 +42,8 @@ class DateTimeValue(object):
         return self.element.get_attribute('value')
 
     # As per the W3C "time" element specification
     # (http://dev.w3.org/html5/markup/input.time.html), this value is formatted
     # according to RFC 3339: http://tools.ietf.org/html/rfc3339#section-5.6
     @time.setter
     def time(self, time_value):
         self.element.send_keys(time_value.strftime('%H:%M:%S'))
-
--- a/testing/marionette/client/marionette_driver/decorators.py
+++ b/testing/marionette/client/marionette_driver/decorators.py
@@ -3,24 +3,26 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from errors import MarionetteException
 from functools import wraps
 import socket
 import sys
 import traceback
 
+
 def _find_marionette_in_args(*args, **kwargs):
     try:
         m = [a for a in args + tuple(kwargs.values()) if hasattr(a, 'session')][0]
     except IndexError:
         print("Can only apply decorator to function using a marionette object")
         raise
     return m
 
+
 def do_crash_check(func, always=False):
     """Decorator which checks for crashes after the function has run.
 
     :param always: If False, only checks for crashes if an exception
                    was raised. If True, always checks for crashes.
     """
     @wraps(func)
     def _(*args, **kwargs):
@@ -40,16 +42,17 @@ def do_crash_check(func, always=False):
                 if not always:
                     check()
             raise exc, val, tb
         finally:
             if always:
                 check()
     return _
 
+
 def uses_marionette(func):
     """Decorator which creates a marionette session and deletes it
     afterwards if one doesn't already exist.
     """
     @wraps(func)
     def _(*args, **kwargs):
         m = _find_marionette_in_args(*args, **kwargs)
         delete_session = False
@@ -61,23 +64,24 @@ def uses_marionette(func):
         ret = func(*args, **kwargs)
 
         if delete_session:
             m.delete_session()
 
         return ret
     return _
 
+
 def using_context(context):
     """Decorator which allows a function to execute in certain scope
     using marionette.using_context functionality and returns to old
     scope once the function exits.
     :param context: Either 'chrome' or 'content'.
     """
     def wrap(func):
-         @wraps(func)
-         def inner(*args, **kwargs):
-             m = _find_marionette_in_args(*args, **kwargs)
-             with m.using_context(context):
-                 return func(*args, **kwargs)
+        @wraps(func)
+        def inner(*args, **kwargs):
+            m = _find_marionette_in_args(*args, **kwargs)
+            with m.using_context(context):
+                return func(*args, **kwargs)
 
-         return inner
+        return inner
     return wrap
--- a/testing/marionette/client/marionette_driver/errors.py
+++ b/testing/marionette/client/marionette_driver/errors.py
@@ -1,14 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
 import traceback
-import types
 
 
 class InstallGeckoError(Exception):
     pass
 
 
 class MarionetteException(Exception):
 
@@ -59,16 +58,17 @@ class ElementNotSelectableException(Mari
 
 class InvalidArgumentException(MarionetteException):
     status = "invalid argument"
 
 
 class InvalidSessionIdException(MarionetteException):
     status = "invalid session id"
 
+
 class TimeoutException(MarionetteException):
     code = (21,)
     status = "timeout"
 
 
 class JavascriptException(MarionetteException):
     code = (17,)
     status = "javascript error"
@@ -93,18 +93,18 @@ class ScriptTimeoutException(MarionetteE
     code = (28,)
     status = "script timeout"
 
 
 class ElementNotVisibleException(MarionetteException):
     code = (11,)
     status = "element not visible"
 
-    def __init__(
-        self, message="Element is not currently visible and may not be manipulated",
+    def __init__(self,
+                 message="Element is not currently visible and may not be manipulated",
                  stacktrace=None, cause=None):
         super(ElementNotVisibleException, self).__init__(
             message, cause=cause, stacktrace=stacktrace)
 
 
 class ElementNotAccessibleException(MarionetteException):
     code = (56,)
     status = "element not accessible"
--- a/testing/marionette/client/marionette_driver/expected.py
+++ b/testing/marionette/client/marionette_driver/expected.py
@@ -10,68 +10,73 @@ from marionette import HTMLElement
 """This file provides a set of expected conditions for common use
 cases when writing Marionette tests.
 
 The conditions rely on explicit waits that retries conditions a number
 of times until they are either successfully met, or they time out.
 
 """
 
+
 class element_present(object):
     """Checks that a web element is present in the DOM of the current
     context.  This does not necessarily mean that the element is
     visible.
 
     You can select which element to be checked for presence by
     supplying a locator::
 
         el = Wait(marionette).until(expected.element_present(By.ID, "foo"))
 
     Or by using a function/lambda returning an element::
 
-        el = Wait(marionette).until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
+        el = Wait(marionette).\
+                until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
 
     :param args: locator or function returning web element
     :returns: the web element once it is located, or False
 
     """
 
     def __init__(self, *args):
         if len(args) == 1 and isinstance(args[0], types.FunctionType):
             self.locator = args[0]
         else:
             self.locator = lambda m: m.find_element(*args)
 
     def __call__(self, marionette):
         return _find(marionette, self.locator)
 
+
 class element_not_present(element_present):
     """Checks that a web element is not present in the DOM of the current
     context.
 
     You can select which element to be checked for lack of presence by
     supplying a locator::
 
         r = Wait(marionette).until(expected.element_not_present(By.ID, "foo"))
 
     Or by using a function/lambda returning an element::
 
-        r = Wait(marionette).until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
+        r = Wait(marionette).\
+                until(expected.element_present(lambda m: m.find_element(By.ID, "foo")))
 
     :param args: locator or function returning web element
     :returns: True if element is not present, or False if it is present
 
     """
 
     def __init__(self, *args):
         super(element_not_present, self).__init__(*args)
 
     def __call__(self, marionette):
         return not super(element_not_present, self).__call__(marionette)
 
+
 class element_stale(object):
     """Check that the given element is no longer attached to DOM of the
     current context.
 
     This can be useful for waiting until an element is no longer
     present.
 
     Sample usage::
@@ -92,69 +97,74 @@ class element_stale(object):
     def __call__(self, marionette):
         try:
             # Calling any method forces a staleness check
             self.el.is_enabled()
             return False
         except errors.StaleElementException:
             return True
 
+
 class elements_present(object):
     """Checks that web elements are present in the DOM of the current
     context.  This does not necessarily mean that the elements are
     visible.
 
     You can select which elements to be checked for presence by
     supplying a locator::
 
         els = Wait(marionette).until(expected.elements_present(By.TAG_NAME, "a"))
 
     Or by using a function/lambda returning a list of elements::
 
-        els = Wait(marionette).until(expected.elements_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
+        els = Wait(marionette).\
+                until(expected.elements_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
 
     :param args: locator or function returning a list of web elements
     :returns: list of web elements once they are located, or False
 
     """
 
     def __init__(self, *args):
         if len(args) == 1 and isinstance(args[0], types.FunctionType):
             self.locator = args[0]
         else:
             self.locator = lambda m: m.find_elements(*args)
 
     def __call__(self, marionette):
         return _find(marionette, self.locator)
 
+
 class elements_not_present(elements_present):
     """Checks that web elements are not present in the DOM of the
     current context.
 
     You can select which elements to be checked for not being present
     by supplying a locator::
 
         r = Wait(marionette).until(expected.elements_not_present(By.TAG_NAME, "a"))
 
     Or by using a function/lambda returning a list of elements::
 
-        r = Wait(marionette).until(expected.elements_not_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
+        r = Wait(marionette).\
+                until(expected.elements_not_present(lambda m: m.find_elements(By.TAG_NAME, "a")))
 
     :param args: locator or function returning a list of web elements
     :returns: True if elements are missing, False if one or more are
         present
 
     """
 
     def __init__(self, *args):
         super(elements_not_present, self).__init__(*args)
 
     def __call__(self, marionette):
         return not super(elements_not_present, self).__call__(marionette)
 
+
 class element_displayed(object):
     """An expectation for checking that an element is visible.
 
     Visibility means that the element is not only displayed, but also
     has a height and width that is greater than 0 pixels.
 
     Stale elements, meaning elements that have been detached from the
     DOM of the current context are treated as not being displayed,
@@ -188,16 +198,17 @@ class element_displayed(object):
             self.el = _find(marionette, self.locator)
         if not self.el:
             return False
         try:
             return self.el.is_displayed()
         except errors.StaleElementException:
             return False
 
+
 class element_not_displayed(element_displayed):
     """An expectation for checking that an element is not visible.
 
     Visibility means that the element is not only displayed, but also
     has a height and width that is greater than 0 pixels.
 
     Stale elements, meaning elements that have been detached fom the
     DOM of the current context are treated as not being displayed,
@@ -220,73 +231,78 @@ class element_not_displayed(element_disp
     """
 
     def __init__(self, *args):
         super(element_not_displayed, self).__init__(*args)
 
     def __call__(self, marionette):
         return not super(element_not_displayed, self).__call__(marionette)
 
+
 class element_selected(object):
     """An expectation for checking that the given element is selected.
 
     :param element: the element to be selected
     :returns: True if element is selected, False otherwise
 
     """
 
     def __init__(self, element):
         self.el = element
 
     def __call__(self, marionette):
         return self.el.is_selected()
 
+
 class element_not_selected(element_selected):
     """An expectation for checking that the given element is not
     selected.
 
     :param element: the element to not be selected
     :returns: True if element is not selected, False if selected
 
     """
 
     def __init__(self, element):
         super(element_not_selected, self).__init__(element)
 
     def __call__(self, marionette):
         return not super(element_not_selected, self).__call__(marionette)
 
+
 class element_enabled(object):
     """An expectation for checking that the given element is enabled.
 
     :param element: the element to check if enabled
     :returns: True if element is enabled, False otherwise
 
     """
 
     def __init__(self, element):
         self.el = element
 
     def __call__(self, marionette):
         return self.el.is_enabled()
 
+
 class element_not_enabled(element_enabled):
     """An expectation for checking that the given element is disabled.
 
     :param element: the element to check if disabled
     :returns: True if element is disabled, False if enabled
 
     """
 
     def __init__(self, element):
         super(element_not_enabled, self).__init__(element)
 
     def __call__(self, marionette):
         return not super(element_not_enabled, self).__call__(marionette)
 
+
 def _find(marionette, func):
     el = None
 
     try:
         el = func(marionette)
     except errors.NoSuchElementException:
         pass
 
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -126,18 +126,18 @@ class GeckoInstance(object):
             process_args['stream'] = sys.stdout
         else:
             process_args['logfile'] = self.gecko_log
 
         env = os.environ.copy()
 
         # environment variables needed for crashreporting
         # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting
-        env.update({ 'MOZ_CRASHREPORTER': '1',
-                     'MOZ_CRASHREPORTER_NO_REPORT': '1', })
+        env.update({'MOZ_CRASHREPORTER': '1',
+                    'MOZ_CRASHREPORTER_NO_REPORT': '1'})
         self.runner = Runner(
             binary=self.bin,
             profile=self.profile,
             cmdargs=['-no-remote', '-marionette'] + self.app_args,
             env=env,
             symbols_path=self.symbols_path,
             process_args=process_args)
         self.runner.start()
@@ -158,16 +158,17 @@ class GeckoInstance(object):
             self.profile = None
 
         if prefs:
             self.prefs = prefs
         else:
             self.prefs = None
         self.start()
 
+
 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:
             # GeckoInstance.start will clone the profile.
             kwargs['profile'] = os.path.join(os.path.dirname(bin),
                                              'gaia',
--- a/testing/marionette/client/marionette_driver/gestures.py
+++ b/testing/marionette/client/marionette_driver/gestures.py
@@ -1,21 +1,25 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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 import MultiActions, Actions
 
-#axis is y or x
-#direction is 0 for positive, and -1 for negative
-#length is the total length we want to scroll
-#increments is how much we want to move per scrolling
-#wait_period is the seconds we wait between scrolling
-#scroll_back is whether we want to scroll back to original view
-def smooth_scroll(marionette_session, start_element, axis, direction, length, increments=None, wait_period=None, scroll_back=None):
+
+def smooth_scroll(marionette_session, start_element, axis, direction,
+                  length, increments=None, wait_period=None, scroll_back=None):
+    """
+        :param axis:  y or x
+        :param direction: 0 for positive, and -1 for negative
+        :param length: total length of scroll scroll
+        :param increments: Amount to be moved per scrolling
+        :param wait_period: Seconds to wait between scrolling
+        :param scroll_back: Scroll back to original view?
+    """
     if axis not in ["x", "y"]:
         raise Exception("Axis must be either 'x' or 'y'")
     if direction not in [-1, 0]:
         raise Exception("Direction must either be -1 negative or 0 positive")
     increments = increments or 100
     wait_period = wait_period or 0.05
     scroll_back = scroll_back or False
     current = 0
@@ -37,23 +41,26 @@ def smooth_scroll(marionette_session, st
     if scroll_back:
         offset = [-value for value in offset]
         while (current > 0):
             current -= increments
             action.move_by_offset(*offset).wait(wait_period)
     action.release()
     action.perform()
 
-#element is the target
-#x1,x2 are 1st finger starting position relative to the target
-#x3,y3 are 1st finger ending position relative to the target
-#x2,y2 are 2nd finger starting position relative to the target
-#x4,y4 are 2nd finger ending position relative to the target
-#duration is the amount of time in milliseconds we want to complete the pinch.
+
 def pinch(marionette_session, element, x1, y1, x2, y2, x3, y3, x4, y4, duration=200):
+    """
+        :param element: target
+        :param x1, y1: 1st finger starting position relative to the target
+        :param x3, y3: 1st finger ending position relative to the target
+        :param x2, y2: 2nd finger starting position relative to the target
+        :param x4, y4: 2nd finger ending position relative to the target
+        :param duration: Amount of time in milliseconds to complete the pinch.
+    """
     time = 0
     time_increment = 10
     if time_increment >= duration:
         time_increment = duration
     move_x1 = time_increment*1.0/duration * (x3 - x1)
     move_y1 = time_increment*1.0/duration * (y3 - y1)
     move_x2 = time_increment*1.0/duration * (x4 - x2)
     move_y2 = time_increment*1.0/duration * (y4 - y2)
@@ -65,19 +72,22 @@ def pinch(marionette_session, element, x
     while (time < duration):
         time += time_increment
         action1.move_by_offset(move_x1, move_y1).wait(time_increment/1000)
         action2.move_by_offset(move_x2, move_y2).wait(time_increment/1000)
     action1.release()
     action2.release()
     multiAction.add(action1).add(action2).perform()
 
-#element: The element to press.
-#time_in_seconds: Time in seconds to wait before releasing the press.
-#x: Optional, x-coordinate to tap, relative to the top-left corner of the element.
-#y: Optional, y-coordinate to tap, relative to the top-leftcorner of the element.
+
 def long_press_without_contextmenu(marionette_session, element, time_in_seconds, x=None, y=None):
+    """
+        :param element: The element to press.
+        :param time_in_seconds: Time in seconds to wait before releasing the press.
+        #x: Optional, x-coordinate to tap, relative to the top-left corner of the element.
+        #y: Optional, y-coordinate to tap, relative to the top-leftcorner of the element.
+    """
     action = Actions(marionette_session)
     action.press(element, x, y)
     action.move_by_offset(0, 0)
     action.wait(time_in_seconds)
     action.release()
     action.perform()
--- a/testing/marionette/client/marionette_driver/keys.py
+++ b/testing/marionette/client/marionette_driver/keys.py
@@ -11,74 +11,74 @@
 # distributed under the License is distributed on an "AS IS" BASIS
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
 
 class Keys(object):
 
-    NULL         = u'\ue000'
-    CANCEL       = u'\ue001' #  ^break
-    HELP         = u'\ue002'
-    BACK_SPACE   = u'\ue003'
-    TAB          = u'\ue004'
-    CLEAR        = u'\ue005'
-    RETURN       = u'\ue006'
-    ENTER        = u'\ue007'
-    SHIFT        = u'\ue008'
-    LEFT_SHIFT   = u'\ue008' #  alias
-    CONTROL      = u'\ue009'
-    LEFT_CONTROL = u'\ue009' #  alias
-    ALT          = u'\ue00a'
-    LEFT_ALT     = u'\ue00a' #  alias
-    PAUSE        = u'\ue00b'
-    ESCAPE       = u'\ue00c'
-    SPACE        = u'\ue00d'
-    PAGE_UP      = u'\ue00e'
-    PAGE_DOWN    = u'\ue00f'
-    END          = u'\ue010'
-    HOME         = u'\ue011'
-    LEFT         = u'\ue012'
-    ARROW_LEFT   = u'\ue012' # alias
-    UP           = u'\ue013'
-    ARROW_UP     = u'\ue013' # alias
-    RIGHT        = u'\ue014'
-    ARROW_RIGHT  = u'\ue014' #  alias
-    DOWN         = u'\ue015'
-    ARROW_DOWN   = u'\ue015' #  alias
-    INSERT       = u'\ue016'
-    DELETE       = u'\ue017'
-    SEMICOLON    = u'\ue018'
-    EQUALS       = u'\ue019'
+    NULL = u'\ue000'
+    CANCEL = u'\ue001'  # ^break
+    HELP = u'\ue002'
+    BACK_SPACE = u'\ue003'
+    TAB = u'\ue004'
+    CLEAR = u'\ue005'
+    RETURN = u'\ue006'
+    ENTER = u'\ue007'
+    SHIFT = u'\ue008'
+    LEFT_SHIFT = u'\ue008'  # alias
+    CONTROL = u'\ue009'
+    LEFT_CONTROL = u'\ue009'  # alias
+    ALT = u'\ue00a'
+    LEFT_ALT = u'\ue00a'  # alias
+    PAUSE = u'\ue00b'
+    ESCAPE = u'\ue00c'
+    SPACE = u'\ue00d'
+    PAGE_UP = u'\ue00e'
+    PAGE_DOWN = u'\ue00f'
+    END = u'\ue010'
+    HOME = u'\ue011'
+    LEFT = u'\ue012'
+    ARROW_LEFT = u'\ue012'  # alias
+    UP = u'\ue013'
+    ARROW_UP = u'\ue013'  # alias
+    RIGHT = u'\ue014'
+    ARROW_RIGHT = u'\ue014'  # alias
+    DOWN = u'\ue015'
+    ARROW_DOWN = u'\ue015'  # alias
+    INSERT = u'\ue016'
+    DELETE = u'\ue017'
+    SEMICOLON = u'\ue018'
+    EQUALS = u'\ue019'
 
-    NUMPAD0      = u'\ue01a' #  numbe pad  keys
-    NUMPAD1      = u'\ue01b'
-    NUMPAD2      = u'\ue01c'
-    NUMPAD3      = u'\ue01d'
-    NUMPAD4      = u'\ue01e'
-    NUMPAD5      = u'\ue01f'
-    NUMPAD6      = u'\ue020'
-    NUMPAD7      = u'\ue021'
-    NUMPAD8      = u'\ue022'
-    NUMPAD9      = u'\ue023'
-    MULTIPLY     = u'\ue024'
-    ADD          = u'\ue025'
-    SEPARATOR    = u'\ue026'
-    SUBTRACT     = u'\ue027'
-    DECIMAL      = u'\ue028'
-    DIVIDE       = u'\ue029'
+    NUMPAD0 = u'\ue01a'  # numbe pad  keys
+    NUMPAD1 = u'\ue01b'
+    NUMPAD2 = u'\ue01c'
+    NUMPAD3 = u'\ue01d'
+    NUMPAD4 = u'\ue01e'
+    NUMPAD5 = u'\ue01f'
+    NUMPAD6 = u'\ue020'
+    NUMPAD7 = u'\ue021'
+    NUMPAD8 = u'\ue022'
+    NUMPAD9 = u'\ue023'
+    MULTIPLY = u'\ue024'
+    ADD = u'\ue025'
+    SEPARATOR = u'\ue026'
+    SUBTRACT = u'\ue027'
+    DECIMAL = u'\ue028'
+    DIVIDE = u'\ue029'
 
-    F1           = u'\ue031' #  function  keys
-    F2           = u'\ue032'
-    F3           = u'\ue033'
-    F4           = u'\ue034'
-    F5           = u'\ue035'
-    F6           = u'\ue036'
-    F7           = u'\ue037'
-    F8           = u'\ue038'
-    F9           = u'\ue039'
-    F10          = u'\ue03a'
-    F11          = u'\ue03b'
-    F12          = u'\ue03c'
+    F1 = u'\ue031'  # function  keys
+    F2 = u'\ue032'
+    F3 = u'\ue033'
+    F4 = u'\ue034'
+    F5 = u'\ue035'
+    F6 = u'\ue036'
+    F7 = u'\ue037'
+    F8 = u'\ue038'
+    F9 = u'\ue039'
+    F10 = u'\ue03a'
+    F11 = u'\ue03b'
+    F12 = u'\ue03c'
 
-    META         = u'\ue03d'
-    COMMAND      = u'\ue03d'
+    META = u'\ue03d'
+    COMMAND = u'\ue03d'
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -2,17 +2,16 @@
 # 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/.
 
 import base64
 import ConfigParser
 import json
 import os
 import socket
-import StringIO
 import traceback
 import warnings
 
 from contextlib import contextmanager
 
 from decorators import do_crash_check
 from keys import Keys
 
@@ -223,17 +222,17 @@ class Actions(object):
         relative to the top-left corner of the element.
 
         :param element: The element to press on.
         :param x: Optional, x-coordinate to tap, relative to the top-left
          corner of the element.
         :param y: Optional, y-coordinate to tap, relative to the top-left
          corner of the element.
         '''
-        element=element.id
+        element = element.id
         self.action_chain.append(['press', element, x, y])
         return self
 
     def release(self):
         '''
         Sends a 'touchend' event to this element.
 
         May only be called if press() has already be called on this element.
@@ -252,39 +251,43 @@ class Actions(object):
     def move(self, element):
         '''
         Sends a 'touchmove' event at the center of the target element.
 
         :param element: Element to move towards.
 
         May only be called if press() has already be called.
         '''
-        element=element.id
+        element = element.id
         self.action_chain.append(['move', element])
         return self
 
     def move_by_offset(self, x, y):
         '''
-        Sends 'touchmove' event to the given x, y coordinates relative to the top-left of the currently touched element.
+        Sends 'touchmove' event to the given x, y coordinates relative to the
+        top-left of the currently touched element.
 
         May only be called if press() has already be called.
 
         :param x: Specifies x-coordinate of move event, relative to the
          top-left corner of the element.
         :param y: Specifies y-coordinate of move event, relative to the
          top-left corner of the element.
         '''
         self.action_chain.append(['moveByOffset', x, y])
         return self
 
     def wait(self, time=None):
         '''
         Waits for specified time period.
 
-        :param time: Time in seconds to wait. If time is None then this has no effect for a single action chain. If used inside a multi-action chain, then time being None indicates that we should wait for all other currently executing actions that are part of the chain to complete.
+        :param time: Time in seconds to wait. If time is None then this has no effect
+                     for a single action chain. If used inside a multi-action chain,
+                     then time being None indicates that we should wait for all other
+                     currently executing actions that are part of the chain to complete.
         '''
         self.action_chain.append(['wait', time])
         return self
 
     def cancel(self):
         '''
         Sends 'touchcancel' event to the target of the original 'touchstart' event.
 
@@ -306,32 +309,32 @@ class Actions(object):
          element.
 
         This is equivalent to calling:
 
         ::
 
           action.press(element, x, y).release()
         '''
-        element=element.id
+        element = element.id
         self.action_chain.append(['press', element, x, y])
         self.action_chain.append(['release'])
         return self
 
     def double_tap(self, element, x=None, y=None):
         '''
         Performs a double tap on the target element.
 
         :param element: The element to double tap.
         :param x: Optional, x-coordinate of double tap, relative to the
          top-left corner of the element.
         :param y: Optional, y-coordinate of double tap, relative to the
          top-left corner of the element.
         '''
-        element=element.id
+        element = element.id
         self.action_chain.append(['press', element, x, y])
         self.action_chain.append(['release'])
         self.action_chain.append(['press', element, x, y])
         self.action_chain.append(['release'])
         return self
 
     def click(self, element, button=MouseButton.LEFT, count=1):
         '''
@@ -448,16 +451,17 @@ class Actions(object):
     def perform(self):
         """Sends the action chain built so far to the server side for
         execution and clears the current chain of actions."""
         body = {"chain": self.action_chain, "nextId": self.current_id}
         self.current_id = self.marionette._send_message("actionChain", body, key="value")
         self.action_chain = []
         return self
 
+
 class MultiActions(object):
     '''
     A MultiActions object represents a sequence of actions that may be
     performed at the same time. Its intent is to allow the simulation
     of multi-touch gestures.
     Usage example:
 
     ::
@@ -482,17 +486,17 @@ class MultiActions(object):
     def add(self, action):
         '''
         Adds a set of actions to perform.
 
         :param action: An Actions object.
         '''
         self.multi_actions.append(action.action_chain)
         if len(action.action_chain) > self.max_length:
-          self.max_length = len(action.action_chain)
+            self.max_length = len(action.action_chain)
         return self
 
     def perform(self):
         """Perform all the actions added to this object."""
         body = {"value": self.multi_actions, "max_length": self.max_length}
         self.marionette._send_message("multiAction", body)
 
 
@@ -526,18 +530,18 @@ class Alert(object):
         tab modal dialog."""
         body = {"value": Marionette.convert_keys(*string)}
         self.marionette._send_message("sendKeysToDialog", body)
 
 
 class Marionette(object):
     """Represents a Marionette connection to a browser or device."""
 
-    CONTEXT_CHROME = 'chrome' # non-browser content: windows, dialogs, etc.
-    CONTEXT_CONTENT = 'content' # browser content: iframes, divs, etc.
+    CONTEXT_CHROME = 'chrome'  # non-browser content: windows, dialogs, etc.
+    CONTEXT_CONTENT = 'content'  # browser content: iframes, divs, etc.
     TIMEOUT_SEARCH = 'implicit'
     TIMEOUT_SCRIPT = 'script'
     TIMEOUT_PAGE = 'page load'
     DEFAULT_SOCKET_TIMEOUT = 360
     DEFAULT_STARTUP_TIMEOUT = 120
 
     def __init__(self, host='localhost', port=2828, app=None, app_args=None,
                  bin=None, profile=None, addons=None,
@@ -633,17 +637,16 @@ class Marionette(object):
         timeout = timeout or self.DEFAULT_STARTUP_TIMEOUT
         return transport.wait_for_port(self.host, self.port, timeout=timeout)
 
     @do_crash_check
     def raise_for_port(self, port_obtained):
         if not port_obtained:
             raise IOError("Timed out waiting for port!")
 
-
     @do_crash_check
     def _send_message(self, name, params=None, key=None):
         """Send a blocking message to the server.
 
         Marionette provides an asynchronous, non-blocking interface and
         this attempts to paper over this by providing a synchronous API
         to the user.
 
@@ -688,18 +691,18 @@ class Marionette(object):
             self._handle_error(err)
 
         if key is not None:
             return self._unwrap_response(res.get(key))
         else:
             return self._unwrap_response(res)
 
     def _unwrap_response(self, value):
-        if isinstance(value, dict) and \
-        (WEBELEMENT_KEY in value or W3C_WEBELEMENT_KEY in value):
+        if isinstance(value, dict) and (WEBELEMENT_KEY in value or
+                                        W3C_WEBELEMENT_KEY in value):
             if value.get(WEBELEMENT_KEY):
                 return HTMLElement(self, value.get(WEBELEMENT_KEY))
             else:
                 return HTMLElement(self, value.get(W3C_WEBELEMENT_KEY))
         elif isinstance(value, list):
             return list(self._unwrap_response(item) for item in value)
         else:
             return value
@@ -733,17 +736,17 @@ class Marionette(object):
         name = None
         crashed = False
         if self.instance:
             if self.instance.runner.check_for_crashes(
                     test_name=self.test_name):
                 crashed = True
         if returncode is not None:
             print ('PROCESS-CRASH | %s | abnormal termination with exit code %d' %
-                (name, returncode))
+                   (name, returncode))
         return crashed
 
     @staticmethod
     def convert_keys(*string):
         typing = []
         for val in string:
             if isinstance(val, Keys):
                 typing.append(val)
@@ -752,97 +755,103 @@ class Marionette(object):
                 for i in range(len(val)):
                     typing.append(val[i])
             else:
                 for i in range(len(val)):
                     typing.append(val[i])
         return typing
 
     def get_permission(self, perm):
+        script = """
+        let value = {
+          'url': document.nodePrincipal.URI.spec,
+          'appId': document.nodePrincipal.appId,
+          'isInIsolatedMozBrowserElement': document.nodePrincipal.isInIsolatedMozBrowserElement,
+          'type': arguments[0]
+        };
+        return value;"""
         with self.using_context('content'):
-            value = self.execute_script("""
-                let value = {
-                              'url': document.nodePrincipal.URI.spec,
-                              'appId': document.nodePrincipal.appId,
-                              'isInIsolatedMozBrowserElement': document.nodePrincipal.isInIsolatedMozBrowserElement,
-                              'type': arguments[0]
-                            };
-                return value;
-                """, script_args=[perm], sandbox='system')
+            value = self.execute_script(script, script_args=[perm], sandbox='system')
 
         with self.using_context('chrome'):
             permission = self.execute_script("""
                 Components.utils.import("resource://gre/modules/Services.jsm");
                 let perm = arguments[0];
                 let secMan = Services.scriptSecurityManager;
-                let attrs = {appId: perm.appId, inIsolatedMozBrowser: perm.isInIsolatedMozBrowserElement};
+                let attrs = {appId: perm.appId,
+                            inIsolatedMozBrowser: perm.isInIsolatedMozBrowserElement};
                 let principal = secMan.createCodebasePrincipal(
                                 Services.io.newURI(perm.url, null, null),
                                 attrs);
                 let testPerm = Services.perms.testPermissionFromPrincipal(
                                principal, perm.type);
                 return testPerm;
                 """, script_args=[value])
         return permission
 
     def push_permission(self, perm, allow):
-        with self.using_context('content'):
-            perm = self.execute_script("""
-                let allow = arguments[0];
-                if (typeof(allow) == "boolean") {
-                    if (allow) {
-                      allow = Components.interfaces.nsIPermissionManager.ALLOW_ACTION;
-                    }
-                    else {
-                      allow = Components.interfaces.nsIPermissionManager.DENY_ACTION;
-                    }
-                }
-                let perm_type = arguments[1];
+        script = """
+        let allow = arguments[0];
+        if (typeof(allow) == "boolean") {
+            if (allow) {
+              allow = Components.interfaces.nsIPermissionManager.ALLOW_ACTION;
+            }
+            else {
+              allow = Components.interfaces.nsIPermissionManager.DENY_ACTION;
+            }
+        }
+        let perm_type = arguments[1];
 
-                Components.utils.import("resource://gre/modules/Services.jsm");
-                window.wrappedJSObject.permChanged = false;
-                window.wrappedJSObject.permObserver = function(subject, topic, data) {
-                  if (topic == "perm-changed") {
-                    let permission = subject.QueryInterface(Components.interfaces.nsIPermission);
-                    if (perm_type == permission.type) {
-                      Services.obs.removeObserver(window.wrappedJSObject.permObserver, "perm-changed");
-                      window.wrappedJSObject.permChanged = true;
-                    }
-                  }
-                };
-                Services.obs.addObserver(window.wrappedJSObject.permObserver,
-                                         "perm-changed", false);
+        Components.utils.import("resource://gre/modules/Services.jsm");
+        window.wrappedJSObject.permChanged = false;
+        window.wrappedJSObject.permObserver = function(subject, topic, data) {
+          if (topic == "perm-changed") {
+            let permission = subject.QueryInterface(Components.interfaces.nsIPermission);
+            if (perm_type == permission.type) {
+              Services.obs.removeObserver(window.wrappedJSObject.permObserver,
+                                          "perm-changed");
+              window.wrappedJSObject.permChanged = true;
+            }
+          }
+        };
+        Services.obs.addObserver(window.wrappedJSObject.permObserver,
+                                 "perm-changed", false);
 
-                let value = {
-                              'url': document.nodePrincipal.URI.spec,
-                              'appId': document.nodePrincipal.appId,
-                              'isInIsolatedMozBrowserElement': document.nodePrincipal.isInIsolatedMozBrowserElement,
-                              'type': perm_type,
-                              'action': allow
-                            };
-                return value;
-                """, script_args=[allow, perm], sandbox='system')
+        let value = {
+          'url': document.nodePrincipal.URI.spec,
+          'appId': document.nodePrincipal.appId,
+          'isInIsolatedMozBrowserElement': document.nodePrincipal.isInIsolatedMozBrowserElement,
+          'type': perm_type,
+          'action': allow
+        };
+        return value;
+        """
+        with self.using_context('content'):
+            perm = self.execute_script(script, script_args=[allow, perm], sandbox='system')
 
         current_perm = self.get_permission(perm['type'])
         if current_perm == perm['action']:
             with self.using_context('content'):
                 self.execute_script("""
                     Components.utils.import("resource://gre/modules/Services.jsm");
-                    Services.obs.removeObserver(window.wrappedJSObject.permObserver, "perm-changed");
+                    Services.obs.removeObserver(window.wrappedJSObject.permObserver,
+                                                "perm-changed");
                     """, sandbox='system')
             return
 
         with self.using_context('chrome'):
             self.execute_script("""
                 Components.utils.import("resource://gre/modules/Services.jsm");
                 let perm = arguments[0];
                 let secMan = Services.scriptSecurityManager;
-                let attrs = {appId: perm.appId, inIsolatedMozBrowser: perm.isInIsolatedMozBrowserElement};
-                let principal = secMan.createCodebasePrincipal(Services.io.newURI(perm.url, null, null),
-                                                               attrs);
+                let attrs = {appId: perm.appId,
+                             inIsolatedMozBrowser: perm.isInIsolatedMozBrowserElement};
+                let principal = secMan.createCodebasePrincipal(Services.io.newURI(perm.url,
+                                                                                  null, null),
+                                                                                  attrs);
                 Services.perms.addFromPrincipal(principal, perm.type, perm.action);
                 return true;
                 """, script_args=[perm])
 
         with self.using_context("content"):
             self.execute_async_script("""
                 let start = new Date();
                 let end = new Date(start.valueOf() + 5000);
@@ -957,17 +966,17 @@ class Marionette(object):
     def enforce_gecko_prefs(self, prefs):
         """
         Checks if the running instance has the given prefs. If not, it will kill the
         currently running instance, and spawn a new instance with the requested preferences.
 
         : param prefs: A dictionary whose keys are preference names.
         """
         if not self.instance:
-            raise errors.MarionetteException("enforce_gecko_prefs can only be called " \
+            raise errors.MarionetteException("enforce_gecko_prefs can only be called "
                                              "on gecko instances launched by Marionette")
         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"]
@@ -1004,24 +1013,24 @@ class Marionette(object):
         : param clean: If False the same profile will be used after the restart. Note
                        that the in app initiated restart always maintains the same
                        profile.
         : param in_app: If True, marionette will cause a restart from within the
                         browser. Otherwise the browser will be restarted immediately
                         by killing the process.
         """
         if not self.instance:
-            raise errors.MarionetteException("restart can only be called " \
+            raise errors.MarionetteException("restart can only be called "
                                              "on gecko instances launched by Marionette")
 
         if in_app:
             if clean:
                 raise ValueError
             # Values here correspond to constants in nsIAppStartup.
-            # See https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppStartup
+            # See http://mzl.la/1X0JZsC
             restart_flags = [
                 "eForceQuit",
                 "eRestart",
             ]
             self._send_message("quitApplication", {"flags": restart_flags})
             self.client.close()
             # The instance is restarting itself; we will no longer be able to
             # track it by pid, so mark it as 'detached'.
@@ -1556,17 +1565,17 @@ class Marionette(object):
             result = self.marionette.execute_script("return global.test1;", new_sandbox=False)
             assert result == "foo"
 
         """
         if script_args is None:
             script_args = []
         args = self.wrapArguments(script_args)
         stack = traceback.extract_stack()
-        frame = stack[-2:-1][0] # grab the second-to-last frame
+        frame = stack[-2:-1][0]  # grab the second-to-last frame
         body = {"script": script,
                 "args": args,
                 "newSandbox": new_sandbox,
                 "sandbox": sandbox,
                 "scriptTimeout": script_timeout,
                 "line": int(frame[1]),
                 "filename": os.path.basename(frame[0])}
         rv = self._send_message("executeScript", body, key="value")
@@ -1606,17 +1615,17 @@ class Marionette(object):
               }, 5000);
             ''')
             assert result == 1
         """
         if script_args is None:
             script_args = []
         args = self.wrapArguments(script_args)
         stack = traceback.extract_stack()
-        frame = stack[-2:-1][0] # grab the second-to-last frame
+        frame = stack[-2:-1][0]  # grab the second-to-last frame
         body = {"script": script,
                 "args": args,
                 "newSandbox": new_sandbox,
                 "sandbox": sandbox,
                 "scriptTimeout": script_timeout,
                 "line": int(frame[1]),
                 "filename": os.path.basename(frame[0]),
                 "debug_script": debug_script}
--- a/testing/marionette/client/marionette_driver/transport.py
+++ b/testing/marionette/client/marionette_driver/transport.py
@@ -2,17 +2,16 @@
 # 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/.
 
 import datetime
 import errno
 import json
 import socket
 import time
-import types
 
 
 class SocketTimeout(object):
     def __init__(self, socket, timeout):
         self.sock = socket
         self.timeout = timeout
         self.old_timeout = None
 
@@ -62,18 +61,18 @@ class Response(Message):
         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)
 
     def to_msg(self):
-       msg = [Response.TYPE, self.id, self.error, self.result]
-       return json.dumps(msg)
+        msg = [Response.TYPE, self.id, self.error, self.result]
+        return json.dumps(msg)
 
     @staticmethod
     def from_msg(payload):
         data = json.loads(payload)
         assert data[0] == Response.TYPE
         return Response(data[1], data[2], data[3])
 
 
@@ -112,17 +111,17 @@ class TcpTransport(object):
 
         7:MESSAGE
 
     On top of this protocol it uses a Marionette message format, that
     depending on the protocol level offered by the remote server, varies.
     Supported protocol levels are 1 and above.
     """
     max_packet_length = 4096
-    connection_lost_msg = "Connection to Marionette server is lost. Check gecko.log (desktop firefox) or logcat (b2g) for errors."
+    connection_lost_msg = "Connection to Marionette server is lost. Check gecko.log for errors."
 
     def __init__(self, addr, port, socket_timeout=360.0):
         """If `socket_timeout` is `0` or `0.0`, non-blocking socket mode
         will be used.  Setting it to `1` or `None` disables timeouts on
         socket operations altogether.
         """
         self.addr = addr
         self.port = port
@@ -238,26 +237,27 @@ class TcpTransport(object):
             data = json.dumps(obj)
         payload = "%s:%s" % (len(data), data)
 
         totalsent = 0
         while totalsent < len(payload):
             try:
                 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 %d of %d bytes" %
+                                  (totalsent, len(payload)))
                 else:
                     totalsent += sent
 
             except IOError as e:
                 if e.errno == errno.EPIPE:
                     raise IOError("%s: %s" % (str(e), self.connection_lost_msg))
                 else:
                     raise e
+
     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
         if isinstance(obj, Exception):
             err = obj
         else:
--- a/testing/marionette/client/marionette_driver/wait.py
+++ b/testing/marionette/client/marionette_driver/wait.py
@@ -5,16 +5,17 @@
 import collections
 import errors
 import sys
 import time
 
 DEFAULT_TIMEOUT = 5
 DEFAULT_INTERVAL = 0.1
 
+
 class Wait(object):
     """An explicit conditional utility class for waiting until a condition
     evaluates to true or not null.
 
     This will repeatedly evaluate a condition in anticipation for a
     truthy return value, or its timeout to expire, or its waiting
     predicate to become true.
 
@@ -137,19 +138,21 @@ class Wait(object):
         if message:
             message = " with message: %s" % message
 
         raise errors.TimeoutException(
             "Timed out after %s seconds%s" %
             (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):
     def __init__(self):
         self._time = time
 
     def sleep(self, duration):
         self._time.sleep(duration)
 
     @property